先看一个“奇怪”的错误:
#include <iostream>
#include <stdlib.h>
using namespace std;
class A{
private:
int sad;
public:
void f() const;
void f1();
//A(int);
//A();
};
void A::f() const{
cout<<"dfsdfds";
}
void A::f1(){
cout<<"f1";
}
//A::A(int sr){
//}
//A::A(){}
int main(int argc, char *argv[])
{
const A caa;
caa.f();
system("PAUSE");
return 0;
}
当使用缺省构造函数时,“const A a ;”会报错。
但当把构造函数写出来后,就没问题了。
为什么?
好了,为了说明这个问题,先引用两句话:
“const对象必须保证对象的数据成员在其生命期内不被改变”(c++编程思想第二版 第一卷 190页)
“缺省构造函数不做任何初始化工作”(钱能第一版 276页)
既然终生不能改变,那么不在const对象创建的时候初始化又能在什么时候初始化呢?所以只能在const对象创建时进行对象的数据成员的初始化。
但缺省构造函数却不做任何初始化! const对象要求必须在创建时初始化,而缺省构造函数却无法完成这一功能,那么怎么办呢?
只好借助于用户自定义构造函数!而且在这个自定义的构造函数中,必须初始化数据成员,否则不是“沦落”到缺省构造函数的水平了吗?!
现在再看咱们的程序。
当用户没有定义构造函数时,“const A a ;” a这个对象被创建时调用缺省构造函数,但因为是const型的,不能用缺省构造函数,所以会报错。
当用户定义了构造函数 “A::A(){}” 时,虽然它没有(实际上应该)初始化数据成员,但编译器(实际是编译器的设计者)以为它一定会在用户自定义构造函数中初始化数据成员(因为不做这种定义的话,还不如直接用缺省构造函数省事呢,又何必多次一举!),所以编译器一看到有用户自定义的构造函数,就认为它会初始化数据成员,就给它放了行!
它骗过了编译器!
此种情况下编译虽能通过,但却是极其不可取的。我们不应该玩这种欺骗编译器的把戏,编译器是我们的朋友啊。