为什么在构造函数中调用子级中的纯虚函数不起作用?

Why calling pure virtual function imlemented in child inside constructor doesn't work?

本文关键字:函数 不起作用 构造函数 调用 为什么      更新时间:2023-10-16

我试图理解为什么,如果有可能从父构造函数调用子方法。

第一次尝试:

#define prn printf(__FUNCTION__);printf("rn");
class A
{
public:
    A(){init();}
     ~A(){prn;}
     virtual void f(){}
     virtual void init()=0;
};
class B : public A<B>
{
public:
    B(){prn;}
    ~B(){prn;}
    virtual void init(){prn;}
};

用纯虚调用压碎。我猜是因为A()中的init()指向A的虚表中的init()。我用下面这行来确认:

virtual void init()=0{prn};

所以,我尝试了以下操作:

template<typename T>
class A
{
public:
    A(){((T*)this)->init();}
     ~A(){prn;}
     virtual void f(){}
     virtual void init()=0{prn;}
};
class B : public A<B>
{
public:
    B(){prn;}
    ~B(){prn;}
    virtual void init(){prn;}
};

哪个也碾碎了!现在我唯一的猜测是,它的发生是因为虚拟表刚刚被制作,但这只是一个猜测…

谁能解释一下发生了什么事?

谢谢!

当您在基类构造函数中时,派生类的详细信息还没有被填充——这意味着虚拟函数表还没有被完全填充。虚函数表不指向任何派生类函数。

如果从基类构造函数调用虚成员函数,可能会发生以下几种情况:

  1. 如果基类有函数的实现,将调用它。这将是最好的情况。请记住,即使声明为纯虚的,也可以在基类中定义虚成员函数。

  2. 如果基类没有成员函数,则该函数在虚函数表中的表项可能为NULL(初始化良好)或未初始化的值。你可能会得到一个异常抛出或分段冲突,或任何行为——你正在进入未定义行为的领域。