c++的构造函数的两个问题
为什么构造函数和析构函数没有返回值
1. 安全性
构造函数和析构函数是只能在生成对象和对象消亡时调用,其他时间是不能调用的。一个对象是只能生一次,只能死一次。
如果有返回值,就代表着有选择权(即使返回的是void)。编译器调用构造函数只是确定它发生,如果有返回值的话编译器就不得不知道针对返回值该怎么去做,程序员也可以随意调用构造函数了(变成普通函数),这样会威胁到程序的安全。
2. 二义性
构造函数返回的应该是所构造的对象。
比如有如下两个重载的函数:
(1) void func(int a){…}
(2) void func(const A &a){…}
那么,对于如下调用,
(3) func(A()),究竟调用谁?
对于(3),我们希望的是调用(2),但是如果构造函数支持返回值,比如:
class A{
public:
int A(){return 0;}
};
那么,究竟是调用(1)还是(2)?— 用的是(1)
于是,我们的重载体系,乃至整个c++的语法体系都面临二义性问题。
这里的核心是表达式的类型。目前,表达式A()的类型是类A,但如果A::A()有返回类型R,那么表达式A()的类类型应该是R,而不是A,于是就会引发上述的类型问题。
为什么构造函数不能使用virtual关键字修饰
构造函数用来创建一个对象的,而虚函数的运行是建立在对象的基础上,在构造函数执行时,对象尚未形成,所以不能将构造函数定义为虚函数。再继承中,基类的析构函数是需要virtual修饰的。
实际上 虚函数 是存放在对象的头部的虚函数表里的。