行业知识
C++ 之 【类与对象】从入门到精通一条龙服务 最终篇(static成员、友元、匿名对象。。。)
2026-11-07 03:41:52
来源:互联网转载
到用时方恨早,白首方悔挣的少
车到山前没有路,悬崖勒马勒不住
一、再谈构造函数
1.构造函数体赋值
2.初始化列表
3.explicit关键字
二、Static成员
1.概念
2.特性
三、友元
1.友元函数
2.友元类
四、内部类
五、匿名对象
六、拷贝对象时的一些编译器优化
七、完结撒❀
–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–
一、再谈构造函数
1.构造函数体赋值
在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。
class Date{public: Date(int year, int month, int day) { _year = year; _month = month; _day = day; }private: int _year; int _month; int _day;}; 虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。
2.初始化列表
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个**"成员变量"后面跟一个放在括号中的初始值或表达式**。
class Date{public: Date(int year, int month, int day) : _year(year) , _month(month) , _day(day) {} private: int _year; int _month; int _day;}; 【注意】
1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
2. 类中包含以下成员,必须放在初始化列表位置进行初始化:
引用成员变量
const成员变量
自定义类型成员(且该类没有默认构造函数时)
class A{public:A(int a):_a(a){}private:int _a;};class B{public:B(int a, int ref):_aobj(a), _ref(ref), _n(10){}private:A _aobj; // 没有默认构造函数int& _ref; // 引用const int _n; // const }; 3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化。
class Time{public:Time(int hour = 0):_hour(hour){cout public:Date(int day){}private:int _day;Time _t;};int main(){Date d(1);}//编译结果:打印出Time()。public: A(int a) :_a1(a) ,_a2(_a1) {} void Print() { cout A aa(1); aa.Print();}A. 输出1 1B.程序崩溃C.编译不通过D.输出1 随机值public:A(int a,int b = 12):_a(a),_b(b){}private:int _a;int _b;};class B{public: B(int b):_b(b) {}private:int _b;int* p = ((int*)malloc(sizeof(int) * 10));A aa1 = {1,2};//这里对自定义类型赋值使用{},通过隐式类型转换可以直接对自定义变量进行赋值};int main(){A a1 = 3;//发生隐式类型转换(int - A) 编译器不会报错const A& aa1 = 4;//隐式隐形转换会产生临时变量 临时变量具有常性需要加const修饰return 0;}public:explicit A(int a,int b = 12):_a(a),_b(b){}private:int _a;int _b;};class B{public: B(int b):_b(b) {}private:int _b;int* p = ((int*)malloc(sizeof(int) * 10));A aa1 = {1,2};//这里对自定义类型赋值使用{},通过隐式类型转换可以直接对自定义变量进行赋值};int main(){A a1 = 3;//发生隐式类型转换(int - A) 编译器不会报错const A& aa1 = 4;//隐式隐形转换会产生临时变量 临时变量具有常性需要加const修饰return 0;}//报错信息:error C2440: “初始化”: 无法从“int”转换为“A”public:A() { ++_scount; }A(const A& t) { ++_scount; }~A() { --_scount; }static int GetACount() { return _scount; }private:static int _scount;};int A::_scount = 0;void TestA(){cout TestA();cout public:Date(int year = 1, int month = 1, int day = 1): _year(year), _month(month), _day(day){}// d1 _cout Date d1;d1 friend ostream& operator}private:int _year;int _month;int _day;};ostream& operator_cout _cin d._year;_cin d._month;_cin d._day;return _cin;}int main(){Date d;cin d;cout friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量public:Time(int hour = 0, int minute = 0, int second = 0): _hour(hour), _minute(minute), _second(second){}private:int _hour;int _minute;int _second;};class Date{public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}void SetTimeOfDate(int hour, int minute, int second){// 直接访问时间类私有的成员变量_t._hour = hour;_t._minute = minute;_t._second = second;}private:int _year;int _month;int _day;Time _t;};private:static int k;int h;public:class B // B天生就是A的友元{public:void foo(const A& a){cout A::B b;b.foo(A());//这里创建的是匿名对象,下面讲return 0;}public:A(int a = 0):_a(a){cout cout public:int Sum_Solution(int n) {//...return n;}};int main(){A aa1;// 不能这么定义对象,因为编译器无法识别下面是一个函数声明,还是对象定义//A aa1();// 但是我们可以这么定义匿名对象,匿名对象的特点不用取名字,// 但是他的生命周期只有这一行,编译运行我们可以看到下一行他就会自动调用析构函数A();A aa2(2);// 匿名对象在这样场景下就很好用,当然还有一些其他使用场景Solution().Sum_Solution(10);return 0;}public:A(int a = 0):_a(a){cout cout cout _a = aa._a;}return *this;}~A(){cout }A f2(){A aa;return aa;}int main(){// 传值传参A aa1;//调用构造函数f1(aa1);//调用拷贝函数cout
上一篇:宝塔面板数据盘扩容全攻略,轻松解决存储空间不足问题!
下一篇:怎么添加长尾关键词?