C++成员初始化列表
来源:互联网 发布:软件技术支持服务合同 编辑:程序博客网 时间:2024/05/08 02:46
我们知道在C++里,对象的构造是由构造函数完成的,一般的我们会在构造函数体内完成成员的初始化工作,像下面这样:
class X{ public: X(int val) {i =val;j=i;} public: int i; int j;}
这是比较简单的一种情况,因为它没有涉及到有虚函数以及继承链里有虚基类的情况,在有虚函数的情况一下,一般是编译器会在构造函数中(由编译器合成或者是开发着提供)安插vptr指针,并妥当的设置好它的值,使得它指向该类的虚函数表,虚函数表也是在编译期间完成的,这里不再细说。
构造函数的另外一种语法就是本文的主题:成员初始化列表。像下面这样:
class X{ public: X(int val):i(val),j(i){} public: int i; int j;}
成员初始化列表并不是一种函数调用,初始化成员的次序非常讲究,编译器真正初始化成员的顺序是按照它们在类中申明的次序的,而并不是列在成员初始化列表里的顺序,上面的示例中的初始化没有任何问题,咱们再来看一种情况,你会得到一个怪异的结果。
class X{ public: X(int val):j(val),i(j){} public: int i; int j;}
看出区别了吗?成员初始化列表里面的次序发生了变化,我们来简单的测试一下到底有什么不同。
#include <iostream> using std::cout;using std::endl; class X{ public: X(int val):i(val),j(i){} public: int i; int j;};int main(){ X x(100); cout << x.i << endl << x.j << endl; return 0;}
输出:100100
没有任何问题,再来看上面的后一种情况。
#include <iostream> using std::cout;using std::endl; class X{ public: X(int val):j(val),i(j){} public: int i; int j;};int main(){ X x(100); cout << x.i << endl << x.j << endl; return 0;}
输出:10653684100
显然不是我们要的结果,对不对?这是因为,编译器是按照申明次序来进行初始化的,所以先初始化i,这时候j是未初始化过的,因此得到的时候脏数据。gcc/g++编译器能对这种情况给出警告,像下面这样
g++ -c -Wall -O3 hello.cpp -o hello.ohello.cpp: In constructor `X::X(int)':hello.cpp:12: warning: `X::j' will be initialized afterhello.cpp:11: warning: `int X::i'hello.cpp:9: warning: when initialized hereg++ -o hello hello.o
如果没有对成员初始化列表这样的理解,估计大家对这样的警告有所不理解,另外,下面这四种情况下是必须要用成员初始化列表语法来初始化成员的:
1.初始化一个reference member2.初始化一个const member3.调用一个base class的构造函数,而它拥有一组参数4.调用一个member class的构造函数,而它拥有一组参数
最后一点,当成员都是基本类型时,两种构造方法在效率上没有任何区别,当成员有class对象时,情况就不一样,在构造函数体中通过赋值运算符=进行初始化时,会产生临时对象,在用成员初始化列表进行构造时,会直接调用class 成员的copy 构造函数,效率上会有所提升,不过现在的编译器将做何种优化也视不同的编译器而异。举个例子:
class Word{public;Word(){name=0;cnt=0;}public:string name;int cnt;}
编译器对构造函数可能做的扩张如下:
Word::Word(){name.string::String();string temp = string(0);name.string::operator=(temp);temp.string::~string();cnt=0}
继续
class Word{public:Word():name(0){cnt=0;}public:string name;int cnt;}
编译器对构造函数可能做的扩张如下:
Word::Word(){name.string::string(0);cnt = 0;}
完。
- c++——成员初始化列表
- 成员初始化列表
- C++成员初始化列表
- 成员初始化列表
- C++ 成员初始化列表
- C++成员初始化列表
- 成员初始化列表
- C++成员初始化列表
- 成员初始化列表
- C++成员初始化列表
- c++初始化成员列表
- 初始化成员列表
- C++初始化成员列表
- C++ 成员初始化列表
- C++初始化成员列表
- 成员初始化列表
- C++成员初始化列表
- C++初始化成员列表
- 图片处理
- fft 变换后的意义
- c#windows窗体程序设计
- ORA-00845: MEMORY_TARGET not supported on this system
- Android开发中几个有用的习惯
- C++成员初始化列表
- web.xml加载顺序
- c# winform 程序打包部署
- 装ubuntu和windows XP的双系统,出现NTDLR Missing 问题的解决
- 关注静态数据成员
- linux 操作常用基础命令(1)
- 使用spring @Scheduled注解执行定时任务
- tomcat虚拟目录的配置
- Oracle存储过程