4

我有两个问题,我在这里找到的答案并不完全让我满意:

  • 为什么将构造函数声明为虚拟是没有意义的?
  • 当我从构造函数调用虚函数时会发生什么?虚拟表也用了吗?
4

3 回答 3

3

为什么将构造函数声明为虚拟是没有意义的?

在构造函数执行之前,对象是不存在的,所以不存在override之类的东西。

当我从构造函数调用虚函数时会发生什么?虚拟表也用了吗?

它可以。在大多数情况下,如果直接从构造函数执行调用,编译器可以跳过动态调度,因为此时它知道最终的覆盖器是什么。但它不需要执行该优化,即使它可以直接在构造函数中执行此操作,但如果您调用一个非虚拟函数又调用该虚拟函数,它也无法执行此操作。因为可能会为派生类型的对象调用非虚拟函数,所以它必须使用虚拟调度机制。

于 2013-04-10T19:57:29.833 回答
2

调用构造函数时,(尚不存在的)对象的实际类型是非常确定的。所以调用构造函数永远不会是间接的。(通过指针/引用调用时,仅间接调用虚函数。)

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!";
    }
};

http://ideone.com/9aQVIc

于 2013-04-10T19:54:11.693 回答
1

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链接。

于 2013-04-10T19:58:32.410 回答