目录 : 初始化列表 类型转换 static 成员 友元 内部类 匿名对象 初始化列表初始化列表是构造函数在进入函数体{}之前用来给类的成员变量做初始化的语法区分两个完全不同的动作初始化列表初始化成员刚创建直接赋予初值int a10;构造函数体内赋值赋值成员已经创建好了修改它的值int a;a10;语法格式 :classTest{public:// 冒号 : 后面就是初始化列表Test(intx):_a(x),_b(10){// 这里是构造函数体这里写的都是赋值不是初始化}private:int_a;int_b;};规则冒号开头多个成员用逗号隔开一个成员最多只能在初始化列表写一次。✅ 必考三类成员只能在初始化列表初始化放到构造函数体内赋值会直接编译报错const成员变量引用成员变量没有默认构造函数的自定义类对象原理const 和引用一旦分配内存就不能再赋值自定义成员会自动调用默认构造如果没有直接报错⚠️ 超级高频考点初始化顺序成员初始化顺序由类里面成员声明的先后顺序决定和初始化列表书写顺序无关classDemo{public:Demo(intval):b(val),a(b){}private:// 成员变量的声明inta;// 类内先声明 aintb;// 类内后声明 bintc10;// 自己定一个c的缺省值// 如果初始化列表没有对 c 进行初始化则 c 使用这个默认值 10// 如果初始化列表写了c(xxx)会覆盖掉类内默认值};执行顺序先初始化a此时b还没初始化a(b)拿到随机垃圾值初始化列表书写顺序尽量和类内成员声明顺序保持一致规避隐藏 bug总结 : 类型转换之前接触过内置类型和内置类型之间的转换那么现在再来看看内置类型和类类型类类型之间的转换类型转换的特点C支持内置类型隐式类型转换为类类型对象需要有相关内置类型为参数的构造函数构造函数前面加explicit就不再支持隐式类型转换类类型的对象之间也可以隐式转换需要相应的构造函数支持上述这些特点都会在举例说明中体现出来#includeiostreamusingnamespacestd;classA{public:// 如果构造函数加一个explict就不再支持隐式类型转换了// explict A(int a1)// 这里的构造函数参数有相关内置类型A(inta1):_a1(a1){}private:int_a11;int_a22;};voidfunc(constAaa1){}classStack{public:voidPush(constAa){}};// ------------------------------------------intmain(){// 1.内置类型之间的隐式类型转换inti1;doubledi;constdoubleref1i;//中间的临时对象具有常性// 2.内置类型和类类型之间的隐式转换// 需要有相关内置类型为参数的构造函数// 这样写是直接构造Aa1(1);// 这个才涉及到隐式类型转换A a21;// 转换的原理是A的构造函数先借助赋值的这个参数构造出一个临时A对象// 然后再进行拷贝构造a2constAref2a1;constAref31;//三种都可以因为上面的函数参数是用过const修饰的(所以第二种也ok)func(a1);func(1);func();//我们再来看看别的使用场景Stack s1;//这样写有点麻烦了Aa3(3);s1.Push(a3);//我们可以直接这样,方便了很多s1.Push(3);return0;} static 成员static 成员分为static 成员变量和static 成员函数属于类本身不属于任何一个对象 static 成员变量归属不属于某个对象所有对象共享同一份 static 变量。内存不在对象空间里存放在静态区初始化规则高频考点类里面只是声明不能在类内初始化C11 静态常量const static int除外必须在类外单独定义初始化classA{public:staticintnum;// 声明};intA::num100;// 类外定义初始化访问方式A::num;推荐类名::直接访问对象访问 A a;a.num;语法允许但本质还是访问类的静态成员访问权限受public/private/protected控制 static 成员函数classA{public:staticvoidfunc(){coutnumendl;}private:staticintnum;};intA::num10;没有 this 指针最重要考点不能访问普通成员变量 / 普通成员函数普通成员依赖 this只能访问 static 成员变量、static 成员函数调用方式A::func();推荐A a; a.func();语法合法不推荐static 成员函数不能加 constconst 成员函数本质是修饰this指针void func() conststatic 没有 this所以不能写 const 友元友元不是类的成员但是可以访问类里面所有成员public / protected / private友元关系单向、不能继承、不能传递两种形式友元函数、友元类友元函数可以是普通全局函数也可以是别的类的成员函数声明位置随便private / protected / public 区都可以不影响前面加friend✅ 特点不属于这个类没有 this 指针可以访问私有成员声明只需要写在类内定义写在外面不加 friend#includeiostreamusingnamespacestd;classDate{private:intyear,month,day;public:Date(inty,intm,intd):year(y),month(m),day(d){}// 友元函数声明friendvoidPrint(constDated);};// 全局友元函数不是成员函数没有this指针voidPrint(constDated){coutd.year-d.month-d.dayendl;}intmain(){Dated(2026,10,11);Print(d);return0;}友元类friend class Test;Test 类所有成员函数都可以访问当前类的私有成员classDate{private:intyear;public:friendclassTest;// Test是Date的友元类};classTest{public:voidfunc(Dated){coutd.year;// 可以访问Date私有成员}};⚠️ 必考三大性质单向A 是 B 的友元 ≠ B 是 A 的友元需要手动双向声明不能继承父类的友元不会自动变成子类的友元不能传递A 是 B 友元B 是 C 友元A不会自动是 C 友元⚠️ 易错点汇总friend只是声明不是定义友元函数不是成员函数不能用. / -调用friend 声明写在类哪个访问权限区都一样public / private 不影响友元权限友元会破坏封装工程里尽量少用 内部类在一个类的内部定义的类叫内部类 ( 嵌套类 )内部类是独立的类只是作用域在外层类里面#includeiostreamusingnamespacestd;classOuter// 外部类{public:// 内部类classInner{public:voidfunc(){coutinner funcendl;}};};intmain(){// 访问内部类必须加外部类::作用域限定Outer::Inner in;in.func();return0;}✅ 核心考点选择题高频内部类是独立的类不属于外部类对象内部类对象不包含外部类对象没有隐含的 Outer* this 指针外部类对象也不包含内部类对象作用域内部类名字被包裹在外部类作用域外部使用必须Outer::Inner访问权限内部类可以直接访问外部类的所有成员public / protected / private前提拿到外部类对象 / 指针外部类不能直接访问内部类的私有成员需要对象与开放权限默认访问控制如果把内部类写在外部类 private 段外部无法使用这个内部类写在 public外部可以通过Outer::Inner定义对象友元关系互不自动成立外部类不是内部类友元 , 内部类也不是外部类友元只是内部类在域内可以访问外部类成员 匿名对象匿名对象 没有名字的临时对象写法类名(参数)本质纯右值 (prvalue)Q1 : 纯右值是什么?A1 : 本身就是临时的值 / 临时对象没有身份不能持久存在字面量10、3.14、“abc”字符串除外运算表达式结果12匿名对象 A() → 就是纯右值函数返回值返回值不是引用纯右值特点没有名字没有持久内存空间用完马上销毁✅ 核心特点生命周期只在当前这一行语句语句执行完立刻调用析构销毁高频考点classA{public:A(){cout构造endl;}~A(){cout析构endl;}};intmain(){A();// 创建匿名对象本行结束马上析构cout这是下一行endl;return0;}输出顺序构造 → 析构 → 这是下一行有名对象A a;到所在作用域结束才析构二者最大区别匿名对象具有常性不能绑定普通左值引用A只能绑定const AconstArefA();// ✔ 合法引用延长匿名对象生命周期Aref2A();// ❌ 编译报错用 const 引用接收匿名对象临时对象生命周期延长到引用的作用域结束不在本行销毁典型用途临时调用成员函数A().func();函数传参一次性传对象不用单独定义变量函数返回值常配合 RVO 返回值优化减少拷贝隐式类型转换产生的临时对象本质也是匿名对象