标题:构造函数为什么不返回类型


我们知道,C++中的构造函数是没有返回值的。构造函数是一种很特殊的函数,因为他没有返回值。这和‘返回值为void’有极大的差别。返回void时,一般函数并不返回任何东西,但是一般的函数能够选择是否要返回些什么东西。构造函数则绝对不返回任何东西,而且你也没有任何选择。如果它有一个返回值,而且你有权利选择你自己的返回型别(return   type),编译器势必得通过某种方式来知道如何处理那个返回值。

 

在《think in c++》里有这么一段解释C++构造函数为什么没有提供返回值的理由:

 

Both the constructor and destructor are very unusual types of functions: they have no return value. This is distinctly different from a void return value, in which the function returns nothing but you still have the option to make it something else. Constructors and destructors return nothing and you don’t have an option. The acts of bringing an object into and out of the program are special, like birth and death, and the compiler always makes the function calls itself, to make sure they happen. If there were a return value, and if you could select your own, the compiler would somehow have to know what to do with the return value, or the client programmer would have to explicitly call constructors and destructors, which would eliminate their safety.

 

上面的英语说明简单来说就是如果有返回值,就代表着有选择权,即使返回是void编译器调用构造函数只是确定它发生,如果有返回值的话编译器就不得不知道针对返回值该怎么去做,程序员也可以随意调构造函数了,这样会威胁到程序的安全。

 

通过C++中临时对象的使用情况可以看出,构造函数返回的应当是所构造的对象。

比如有如下2个重载的函数:

void func(int a) {...} //(1)

void func(const A& a) {...} //(2)

那么,对于下面的调用:

func(A()); //(3),究竟调用谁?

对于(3),我们希望调用的是(2),但如果构造函数支持返回值,比如A::A()int类型的返回值,那么究竟是调(1)好呢,还是调用(2)好呢。于是,我们的重载体系,乃至整个的C++的语法体系都面临二义性问题。

这里的核心是表达式的类型。目前,表达式A()的类型是类A。但如果A::A()有返回类型R,那么表达式A()的类型应当是R,而不是A,于是便会引发上述的类型问题。

 

为什么构造函数不能使用virtual关键字修饰?

 

构造函数用来创建一个新的对象,而虚函数的运行是建立在对象的基础上(请参见: 多态与虚函数),在构造函数执行时,对象尚未形成,所以不能将构造函数定义为虚函数。 通常析构函数才会用virtual修饰



看文字不过瘾?点击我,进入周哥教IT视频教学
麦洛科菲长期致力于IT安全技术的推广与普及,我们更专业!我们的学员已经广泛就职于BAT360等各大IT互联网公司。详情请参考我们的 业界反馈 《周哥教IT.C语言深学活用》视频

我们的微信公众号,敬请关注