C构造函数初始化列表基本思想1. 基础语法初始化列表以冒号:开头后面跟随以逗号,分隔的成员变量初始化项。每一个成员变量后面紧跟括号括号内为初始值 / 初始化表达式。2. 基础语法规则每个成员变量在初始化列表中只能出现 1 次从语法本质上来说初始化列表就是成员变量定义并初始化的位置一个变量只能定义一次无法重复初始化。三类成员必须强制使用初始化列表初始化以下三种成员变量无法在构造函数函数体内赋值必须在初始化列表完成初始化否则直接编译报错引用类型成员变量const修饰的常量成员变量没有默认构造函数的自定义类对象成员3.C11 类内声明缺省值C11 标准新增语法可以在类内成员变量声明的位置直接给变量赋初始缺省值。4.为什么尽量优先使用初始化列表效率更高函数体内的操作本质是赋值先创建变量、分配内存再往内存里写值初始化列表是定义 初始化一步完成直接在内存开辟时就写入初始值少一步赋值操作。覆盖全部成员初始化场景可以处理引用、const、无默认构造类对象这些函数体内无法初始化的特殊成员。逻辑统一严谨无论你是否显式写初始化列表所有成员变量全部都会走初始化列表流程全程统一初始化逻辑。5.顺序初始化顺序铁则只看类内声明顺序和列表书写顺序无关代码书写建议两者顺序保持一致。优先级顺序初始化列表显式初始化 类内声明缺省值 编译器默认处理内置类型随机值 / 自定义类默认构造代码实现#includeiostream using namespace std; class Time { public: Time(int hour) :_hour(hour) { std::cout Time() endl; } private: int _hour; }; class Date { public: // 初始化列表处理所有强制初始化成员 Date(int x, int year 1, int month 1, int day 1) :_year(year) ,_day(day) , _month(month) , _ref(x) // 引用成员必须初始化列表初始化 ,_i(10) // const成员必须初始化列表初始化 ,_t(1) // 无默认构造的类对象必须初始化列表初始化 { } private: int _year 2000; // 类内缺省值被初始化列表覆盖 int _month; int _day 1; int _ref; // 引用特殊成员 const int _i 100; // const特殊成员 Time _t; // 自定义类对象无默认构造 };C类型转换基本思想1. 核心原理课件第一点C 支持内置类型隐式类型转换为类类型对象需要有相关内置类型为参数的构造函数。概念通俗解释内置类型C 自带基础类型比如int、double、char类类型对象我们自己写的类实例化出来的对象隐式转换编译器自动、偷偷完成类型转换你不需要手动写转换语法编译器自动调用构造函数把数字转成类对象。前提条件你的类中必须存在对应内置类型作为单个参数的构造函数。转换本质所有类相关的隐式转换本质都是编译器自动调用构造函数创建临时对象。隐式转换全程都是构造函数在工作。代码实现#include iostream using namespace std; class Date { public: // 单个int类型参数的构造函数 // 支持int 类型 隐式转换为 Date类对象 Date(int day) { _day day; cout 单参构造函数调用隐式转换生效 endl; } void Print() { cout _day endl; } private: int _day; }; void fun(Date d) { d.Print(); } int main() { // 核心隐式转换演示 // 1. 直接用int数字给Date对象赋值 Date d 10; // 编译器自动转换等价于 Date d Date(10); 自动调用构造函数 // 2. 函数形参需要Date对象实参直接传int数字 fun(20); // 编译器自动转换等价于 fun(Date(20)); 自动构造临时对象传入 return 0; }explicit 关键字基本思想构造函数前面加 explicit 就不再支持隐式类型转换。explicit中文含义显式的。作用修饰单参数构造函数直接彻底关闭编译器自动隐式转换的能力。只有你手动显式写构造才能创建对象编译器绝不自动偷偷转换。代码实现#include iostream using namespace std; class Date { public: // 加上 explicit 关键字关闭隐式转换 explicit Date(int day) { _day day; cout explicit修饰仅支持显式构造 endl; } void Print() { cout _day endl; } private: int _day; }; void fun(Date d) { d.Print(); } int main() { // Date d 10; // 直接编译报错隐式转换被禁止 // fun(20); // 直接编译报错无法自动转换 // 只能手动显式构造对象 Date d(10); d.Print(); fun(Date(20)); return 0; }Cstatic成员基本思想一、静态成员变量1. 基础定义用static关键字修饰的类成员变量称之为静态成员变量。2. 核心特性初始化规则必须在类外全局作用域初始化静态成员变量只能在类外部进行初始化不能在类内声明位置赋初始缺省值。原因普通成员变量属于对象走构造函数初始化列表而静态成员不属于任何对象不参与构造函数的初始化流程类内声明仅仅是「告诉编译器有这个变量」真正的内存开辟、初始化必须在类外完成。内存归属与共享特性静态成员变量不属于某一个具体的对象不存储在对象内存空间中全部存放在程序的全局静态数据区。整个类创建的所有对象全程共用这一份静态变量所有对象操作的都是同一块内存二、静态成员函数1. 基础定义用static关键字修饰的类成员函数称之为静态成员函数。2. 核心灵魂没有 this 指针静态成员函数没有this指针this指针的作用指向调用该函数的具体对象。而静态成员函数属于类、不属于对象调用不需要依托任何对象天生没有绑定的实例因此不存在 this 指针。3. 访问权限规则重中之重考试必考规则 1静态成员函数内部可以访问同类的静态成员静态变量、静态函数绝对不能访问同类的非静态成员变量、非静态成员函数原因非静态成员全部依赖this指针绑定具体对象而静态函数没有this指针无法定位对象成员。规则 2普通非静态成员函数内部可以无限制访问静态成员 非静态所有成员原因普通成员函数自带this指针既能访问自身对象成员也能直接访问类全局共享的静态成员。4、访问权限限定符静态成员本质依旧是类的成员完全受public/protected/private访问权限控制。公有public静态成员类内外任意位置都可访问私有private静态成员只能在类内部访问类外部无法直接访问哪怕是类名::也不行只能通过类内成员函数获取。静态成员变量不能在声明位置给缺省值初始化代码实现class Solution { // 内部嵌套类 class Sum { public: Sum() { _ret _i; _i; } }; public: int Sum_Solution(int n) { Sum* arr new Sum[n]; return _ret; } private: static int _i; // 类内静态成员声明 static int _ret; }; // 必须类外全局初始化 int Solution::_i 1; int Solution::_ret 0;友元和内部类基本思想1. 友元基础概念C 的类通过public/protected/private实现数据封装严格限制外部访问类内私有成员。而友元就是专门提供了突破类访问限定符封装的特殊语法。友元一共分为两大类友元函数、友元类。语法核心在函数 / 类声明前加friend关键字并且必须把友元声明写在类的内部。2. 友元函数1核心特性外部的友元函数可以直接访问类内所有私有、保护成员突破权限限制。友元函数不属于类的成员函数仅仅只是一个外部全局函数只是获得了类的访问特权。友元函数没有this指针不属于对象。友元函数可以在类定义内的任意位置声明不受public/protected/private访问权限的限制声明在哪一块区域都不影响权限。通用性一个函数可以同时是多个不同类的友元函数同时获得多个类的私有成员访问权限。3. 友元类1核心特性若 A 类是 B 类的友元类A 类中所有的成员函数全部都是 B 类的友元函数。A 类所有成员函数都可以无限制访问 B 类内所有私有、保护成员。友元关系是单向的不具备交换性口诀A 是 B 的友元B 不是 A 的友元。只有 A 能访问 B 的私有成员B 无法反过来访问 A 的私有成员。友元关系不可传递口诀A 是 B 的友元B 是 C 的友元A 不是 C 的友元。友元特权不会层层继承、传递必须单独显式声明。4.内部类1. 内部类基础概念内部类把一个类的完整定义写在另一个外部类的类体大括号内部这个嵌套在内的类就叫做内部类。核心基础特性内部类本质是一个完全独立的类和全局定义的类没有本质区别。唯一限制受外部类的类域限制 访问限定符限制。外部类创建的对象内存中完全不包含内部类内部类有自己独立的内存空间和外部类对象内存无关。2. 内部类核心特权内部类默认天生就是外部类的友元类这是考试最高频考点内部类无需额外写friend声明默认自带友元权限可以直接访问外部类所有的私有成员、静态成员。完美对应你之前写的「1~n 求和嵌套类代码」3. 内部类的封装作用内部类本质是高级的类封装语法当两个类业务强绑定A 类仅专门给 B 类使用不会在其他地方复用就可以把 A 设计为 B 的内部类。若内部类声明在外部类的private/protected权限区域这个内部类就成为外部类的专属私有类除了外部类自身程序其他所有位置都无法定义、使用这个内部类完美实现极致封装。代码实现#include iostream using namespace std; class Solution { // 内部类Sum定义在外部类Solution内部 class Sum { public: Sum() { // 内部类默认是外部类友元直接访问外部类private静态私有成员 _ret _i; _i; } }; public: int Sum_Solution(int n) { Sum* arr new Sum[n]; return _ret; } private: // 外部类私有静态成员 static int _i; static int _ret; }; // 外部类静态成员类外初始化 int Solution::_i 1; int Solution::_ret 0; int main() { Solution s; cout s.Sum_Solution(10) endl; // 输出55 return 0; }