小工具知识网

当前位置: 首页 > 行业知识 > C++ 之 【类与对象】从入门到精通一条龙服务 最终篇(static成员、友元、匿名对象。。。)

行业知识

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 

上一篇:宝塔面板数据盘扩容全攻略,轻松解决存储空间不足问题!

下一篇:怎么添加长尾关键词?