行业知识
【C++】类与对象—— 初始化列表 、static 静态成员、
2026-11-08 03:23:52
来源:互联网转载
类与对象
- 1 再谈构造函数
- 1.1 构造函数体赋值
- 1.2 初始化列表
- 语法:
- 建议:
- 初始化顺序:
- 注意:
- 1.3 explicit关键字
- 2 static 静态成员
- 2.1 概念
- 2.2 声明成员变量
- 2.3 使用类的静态成员
- 2.4 定义静态成员
- 总结
- Thanks♪(・ω・)ノ谢谢阅读!!!
- 下一���文章见!!!
1 再谈构造函数
1.1 构造函数体赋值
在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值,以我们之前实现的Date类对象为例。
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 初始化列表
语法:
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。
class Date{public:Date(int year, int month, int day):_year(year),_month(month),_day(day){ }private:int _year;int _month;int _day;};建议:
有时我们可以忽略数据成员初始化的和赋值之间的差异,但并非总是这样。
如果成员是const 或 引用变量的话,必须将其初始化。类似的如果存在自定义类型并且该类不存在构造函数时,也必须将其初始化。例如:
class A {private:int a;};class Date{public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}private:const int _year;int& _month;int _day;A a;};int main(){const Date a1(2024,2,24);return 0;}来看看报错:
显然我们需要初始化来帮助我们解决这些问题。
在很多类中初始化和赋值的区别事关底层效率的问题:前者直接初始化数据成员,后者则先初始化再赋值。除了效率问题外更重要的是,一些数据成员必须初始化。所以一般建议养成使用初始化列表的习惯,这样可以避免某些意想不到的编译错误,特别是遇到类包含构造函数初始值的成员时。
初始化顺序:
显然在构造函数中每个成员只能出现一次。否则给同一个成员赋两个不同初始值有什么意义呢?
需要注意的是初始化列表不限定初始化的执行顺序,因为成员初始化的顺序与他们在类出现顺序一致,第一个成员先初始化,然后第二个,以此类推,因此构造函数初始化列表的前后位置并不影响实际的初始化顺序。
但是下面这个例子不同:
class A{public:A(int a):_a1(a),_a2(_a1){}void Print() {cout A aa(1);aa.Print();}public:// 1. 单参构造函数,没有使用explicit修饰,具有类型转换作用// explicit修饰构造函数,禁止类型转换---explicit去掉之后,代码可以通过编译 explicit Date(int year) :_year(year) {}private: int _year; int _month; int _day;};void Test(){ Date d1(2022); // 用一个整形变量给日期类型对象赋值 // 实际编译器背后会用2023构造一个无名对象, //最后用无名对象给d1对象进行赋值}public:// 2. 虽然有多个参数,但是创建对象时后两个参数可以不传递,//没有使用explicit修饰,具有类型转换作用// explicit修饰构造函数,禁止类型转换explicit Date(int year, int month = 1, int day = 1): _year(year), _month(month), _day(day){}Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}private:int _year;int _month;int _day;};void Test(){Date d1(2022);// 用一个整形变量给日期类型对象赋值// 实际编译器背后会用2023构造一个无名对象,//最后用无名对象给d1对象进行赋值d1 = 2023;// 将 1 屏蔽掉,2放开时则编译失败,因为explicit修饰构造函数,//禁止了单参构造函数类型转换的作用}public:Date(int year, int month, int day):_year(year),_month(month),_day(day){ }static void count();private:int _year;int _month;int _day;};void count(){};int main(){Date d1;Date* d2 = &d1; d2-count();d1.count();return 0;}
上一篇:腾讯云宝塔面板轻松开启指南
下一篇:怎么安装pvg服务器?