首页 > 代码库 > C++ Constructors FAQ

C++ Constructors FAQ

最近对c++的构造函数产生了疑问?即而找到了一篇介绍这些知识的文章,苦于是英文的于是便打算将其翻译下,第一次翻译,翻译不好的地方请指出,谢谢。

Q: 默认构造函数到底是什么?

答:很多程序员认为默认构造函数是当用户没有显示定义一个构造函数时,编译器自动的为我们合成一个默认的构造函数。其实这是错误的(这个在深入理解C++对象模型里面也有详细的介绍),一个默认构造函数可以是程序员定义也可以是编译器合成的。所谓的默认构造函数是当且仅当类能在没有任何参数时所调用的构造函数。如下:

 

struct A
{
int x;
A(): x(0) {}
};
struct B: A
{
//no user-defined ctor.
//the compiler implicitly declares a default constructor
};
class C
{
public:
explicit C(int n=0, int m=0); // may be invoked with no arguments
};
C c0, c2(9,0);

其中C中的构造函数有参数列便,但是它依然能够以无参的默认形式调用,故而也可以看成默认构造函数。如若你把int n=0,int m=0;中提供默认值给去掉C c0这句语句便不能通过编译。

Q:编译器到底什么时候隐式的声明一个默认构造函数呢?

答:如果该类不包含任何引用或const data,编译器会为所有没有声明默认构造函数的类隐式的声明一个默认构造函数,值得注意的地方是若你显示的申明了拷贝构造函数,编译器也是会不生成默认构造函数的。(由于const 或引用需要初始化,默认构造函数并不知怎么去初始化他们,故而不产生默认构造函数).

class A2
{
 int x;
public:
 A2(const A2&); //the access type doesn’t matter, it could be private or protected too
void f();
}; 
A2 a2; //error, A2 has no default constructor 
A2 a3(a2); //a2 cannot be instantiated because no default ctor is available

Q:隐式声明的默认拷贝构造函数到底干了些什么?

答:这个问题也是困扰很多程序员的一大谜题呀,很多人认为隐式声明的默认构造函数背着程序员做了很多不为人知的初始化操作,或者是为对象申请了内存空间。这是个非常无知的想法。真实的情况是隐式声明的默认构造函数完完全全不做任何事情。请记住一件事情:不管你是显示还是隐式的声明一个默认构造函数并不意味着这个构造函数被定义了。如下例子便能看出来:


class B
{
 B(); //declaration only
};
B::B() {} //separate definition of the user-declared default constructor

class C
{
C() {} //declaration and definition
};
class D
{
//implicit declaration of a default constructor, no implicit definition
};
class E
{
//implicit declaration + implicit definition of a default constructor
virtual void f();
};
class F
{
virtual void f();
public:
F(); ////explicit declaration a default constructor, user forgot a definition
F f; //linkage error: symbol ’F::F()’ could not be resolved
};


总结一下:一个用户声明的构造函数永远不会隐式定义,如果程序员自己声明构造函数他便有责任去定义它,除非是有意的去使它处于未完成的状态(例如阻止对象拷贝等)。相对比之下:一个隐式声明的构造函数只有在某些确定的条件下才会被隐式定义。具体的咱见下章。