我有两个问题,我在这里找到的答案并不完全让我满意:
- 为什么将构造函数声明为虚拟是没有意义的?
- 当我从构造函数调用虚函数时会发生什么?虚拟表也用了吗?
为什么将构造函数声明为虚拟是没有意义的?
在构造函数执行之前,对象是不存在的,所以不存在override之类的东西。
当我从构造函数调用虚函数时会发生什么?虚拟表也用了吗?
它可以。在大多数情况下,如果直接从构造函数执行调用,编译器可以跳过动态调度,因为此时它知道最终的覆盖器是什么。但它不需要执行该优化,即使它可以直接在构造函数中执行此操作,但如果您调用一个非虚拟函数又调用该虚拟函数,它也无法执行此操作。因为可能会为派生类型的对象调用非虚拟函数,所以它必须使用虚拟调度机制。
调用构造函数时,(尚不存在的)对象的实际类型是非常确定的。所以调用构造函数永远不会是间接的。(通过指针/引用调用时,仅间接调用虚函数。)
BaseClass *x = new SubClass();
在构造函数中调用虚函数并不符合您的预期。由于子类还没有被初始化,最终类上的虚函数不能被调用(v-table当前指向当前正在执行的构造函数的类)。
class BaseClass {
BaseClass() {
call();
}
virtual void call() {
std::cout << "BaseClass!";
}
};
class SubClass : public BaseClass {
SubClass() : BaseClass()
{
}
void call() {
std::cout << "SubClass!";
}
};
Why declaring a constructor as virtual is meaningless
.
当调用构造函数时,虚拟表在内存中将不可用。在 C++ 中声明一些虚拟的东西意味着它可以被当前类的子类覆盖,但是在创建对象时调用构造函数,那时你不能创建你必须的类的子类创建类,因此永远不需要声明一个虚拟构造函数。virtual constructor
因此,在 C++中没有这样的东西。
What happens when I call a virtual function from a constructor? Is the virtual table used too
有关此问题的详细说明,请参阅C++ FAQ链接。