声明纯虚函数时出现C ++ LNK2001错误

时间:2017-09-15 01:27:47

标签: c++ c++11 pure-virtual

我有两个类,基类A和派生类B.定义如下:

Class A {
public:
    A()
    {
        ImpleDefinition();
    }
    ~A()=default:

protected:
    virtual void ImplDefinition()=0;
}

class B : public A
{
public:
    B() : A()
    {
    }
    ~B()=default;

private:
    void ImplDefinition() override
    {
        /*Some detailed implementation*/
    }
}

因此,在编译此代码时,编译器会报告“错误LNK2001:未解析的外部符号”错误。从代码本身来看,我看不出我犯了什么错误。有趣的是,如果我将“ImplDefinition”从纯虚函数更改为虚函数。

void ImplDefinition() {};

然后一切正常。如何解释这种情况?

2 个答案:

答案 0 :(得分:1)

您正在尝试从同一个类的构造函数中调用纯虚函数。形式上,行为是不确定的。在实践中,最终会出现此类代码的链接器错误。

当从构造函数或析构函数调用虚函数时,虚拟机制在当前层次结构级别“上限”:它“正常”处理正在构造/销毁的类。它永远不会从任何派生的类中看到或调用任何重写的虚函数。

在您的情况下,ImpleDefinition()的构造函数中的A调用没有看到也没有调用B::ImpleDefinition(与您显然的意图相反)。相反,它会尝试调用A::ImpleDefinition。由于未定义A::ImpleDefinition,因此调用失败。

你要做的事情是行不通的,至少在这种形式下是这样。您不能通过调用在派生类中重写的虚函数来“虚拟化”构造函数的行为。

答案 1 :(得分:1)

问题是您在ImplDefinition()中调用虚拟函数A::A()。在基类的构造函数中,当前对象始终是基类子对象,派生类部分根本不构造;这将在稍后进行。然后将调用纯虚拟A::ImplDefinition()并导致错误;这里没有动态调度,根本不会调用B::ImplDefinition()

进一步阅读When my base class’s constructor calls a virtual function on its this object, why doesn’t my derived class’s override of that virtual function get invoked?