构造函数、析构函数、拷贝构造函数、赋值运算符重载、&操作符重载、const &重载 –参考链接
例子:定义一个空类
class Empty
{
}
一个空的class在C++编译器处理过后就不再为空,编译器会自动地为我们声明一些成员函数,代码如下:
class Empty
{
public:
Empty(); // 缺省构造函数
Empty( constEmpty& ); // 拷贝构造函数
~Empty(); // 析构函数
Empty&operator=( const Empty& ); // 赋值运算符
Empty*operator&(); // 取址运算符
const Empty*operator&() const; // 取址运算符const
};
2、成员初始化
利用默认构造函数初始化成员变量
#includeclass A { public: A() = default; void print() { std::cout << "val_a: " << val_a << " &val_a: " << &val_a << std::endl; std::cout << "val_b: " << val_b << " &val_b: " << &val_b << std::endl; std::cout << "val_c: " << val_c << " &val_c: " << &val_c << std::endl; } static int val_static; private: int val_a; int val_b; int val_c ; }; int A::val_static = 1; // 若不赋值,用默认的值,编译器,编译直接不给打印val_static的值 int main() { A a; a.print(); std::cout << "val_static: " << A::val_static << " &val_static: " << &A::val_static << std::endl; // 打印val_static的值 }
- 利用vs debug模式中成员变量值没有初始化,其结果为:
val_a: -858993460 &val_a: 00DEFC30 val_b: -858993460 &val_b: 00DEFC34 val_c: -858993460 &val_c: 00DEFC38 val_static: 1 &val_static: 00CA6000
从上面结果可以看出,成员函数没有给初始值,值都为-858993460(0xcccccccc),且都有分配内存。
- 利用vs debug模式中成员变量值没有初始化,其结果为:
val_a: 0 &val_a: 0136FA68 val_b: 1988144199 &val_b: 0136FA6C val_c: 17113088 &val_c: 0136FA70 val_static: 1 &val_static: 005B4018
从上面的结果可以看出,成员函数没有给初始值,值是随机给的,且都分配内存。
3、初始化成员的先后顺序代码:(参考)
#includeusing namespace std; class A { int a; int b; public: A() :b(0), a(b + 2){ } void print() { cout << "a = " << a << " ,b = " << b << endl; } }; int main() { A a; a.print(); return 0; }
运行结果:
a = 7476729 ,b = 0
从结果可值,类中成员变量初始化的先后次序与变量在类中被定义的先后次序有关,与构造函数中被初始化的先后顺序无关。
4、构造函数初始化调用顺序参考
#includeusing namespace std; class OBJ1{ public: OBJ1(){ cout<<"OBJ1n"; } }; class OBJ2{ public: OBJ2(){ cout<<"OBJ2n";} } class Base1{ public: Base1(){ cout<<"Base1n";} } class Base2{ public: Base2(){ cout <<"Base2n"; } }; class Base3{ public: Base3(){ cout <<"Base3n"; } }; class Base4{ public: Base4(){ cout <<"Base4n"; } }; class Derived :public Base1, virtual public Base2,public Base3, virtual public Base4//继承顺序{ public: Derived() :Base4(), Base3(), Base2(),Base1(), obj2(), obj1(){//初始化列表 cout <<"Derived ok.n"; } protected: OBJ1 obj1;//声明顺序 OBJ2 obj2; }; int main() { Derived aa;//初始化 cout <<"This is ok.n"; return 0; }
结果:
Base2 //虚拟基类按照被继承顺序初始化 Base4 //虚拟基类按照被继承的顺序 Base1 //非虚拟基类按照被继承的顺序初始化 Base3 //非虚拟基类按照被继承的顺序 OBJ1 //成员函数按照声明的顺序初始化 OBJ2 //成员函数按照声明的顺序 Derived ok. This is ok.
由上可知,C++构造函数初始化按下列顺序被调用:
- 首先,任何虚拟基类的构造函数按照它们被继承的顺序构造;
- 其次,任何非虚拟基类的构造函数按照它们被继承的顺序构造;
- 最后,任何成员对象的构造函数按照它们声明的顺序调用;



