虚拟构造函数以及调用其中的虚函数会发生什么

时间:2013-04-10 19:51:19

标签: c++ oop object

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

  • 为什么将构造函数声明为虚拟无意义?
  • 当我从构造函数中调用虚函数时会发生什么?是否也使用了虚拟表?

3 个答案:

答案 0 :(得分:3)

  

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

在执行构造函数之前,该对象不存在,因此没有覆盖这样的东西。

  

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

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

答案 1 :(得分:2)

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

BaseClass *x = new SubClass();

在构造函数中调用虚函数并不能达到预期效果。由于子类尚未初始化,因此无法调用最终类的虚函数(v表当前指向当前正在执行的构造函数的类)。

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

答案 2 :(得分:1)

Why declaring a constructor as virtual is meaningless

调用构造函数时,内存中的虚拟表将不可用。在C ++中声明虚拟化意味着它可以被当前类的子类覆盖,但是当创建了objected时会调用构造函数,那时你不能创建类的子类,你必须是创建类所以永远不需要声明构造函数虚拟。因此,在C ++中没有virtual constructor这样的东西。

What happens when I call a virtual function from a constructor? Is the virtual table used too

有关此问题的详细说明,请参阅C++ FAQ 链接。