1.用构造函数确保初始化
-
构造函数由编译器调用,所以构造函数的名字要与类名字相同,这样的函数在初始化时会被自动被调用。
class X { int i; public: X(); } void f() { X a; }
当程序执行到a的序列点执行的点时,编译器在a的定义点处插入了一个X:X() 的调用,即构造函数自动被调用,此时编译器传给构造函数的第一个参数是 this指针(调用这一对象的地址),这个指针指向一个还未初始化的内存块。构造函数的作用正是正确的初始化该内存块。
-
构造函数与析构函数无返回值,负责对象的出生和死亡,由编译器调用。它们与返回值为void的函数不同。如果它们有返回值,要么编译器必须知道如何处理返回值,要么就只能由客户程序员自己来显示地调用构造函数与析构函数,这样,程序安全性就被破坏了。
2.用析构函数确保清楚
class Y {
public:
~Y();
}
当对象超出它的作用域时,编译器会自动调用析构函数。如下述例子所示:
class Tree {
int height;
public:
Tree(int initialHeight); //Constructor
~Tree(); //Deconstructor
void grow(int years);
void printsize();
};
Tree::Tree(int inittialHeight){
height = inittialHeight;
}
Tree::~Tree(){
cout << "inside tree deconstructor" <<endl;
printsize();
}
void Tree::grow(int years){
height += years;
}
void Tree::printsize(){
cout << "Tree height is "<<endle;
}
int main(){
Tree t(12);
{
cout << "after Time creation" <<endl;
t.printsize();
t.grow(4);
cout << "before closing brace" << endl;
}//在此处编译器自动调用析构函数
cout << "after closing brace" <<endl;
}
输出:
before…
after …
Tree height is 12
before…
inside … //已经调用析构函数
Tree height is 16
after…
3.聚合初始化
- 编译器把列出来的前i个值赋给数组的前i个地址空间
int b[6] = { 1 };
- 若仅仅只是声明,编译器不会做初始化的工作
int b[6] ;
4.默认构造函数
- 若struct对象无默认的空参数构造器,以下定义或声明函数,编译器都会出现错误:
(1)Y Y2[2] = {
Y(1};
(2) Y y3[7];
(3) Y y4;
- 因此,当且仅当一个struct或class无构造函数时,编译器会自动为它创建一个。但我们应该把这当做一种安全机制,尽量自己明确定义自己的构造函数。