【问题标题】:C++ LNK2001 Error When declaring Pure Virtual FunctionC++ LNK2001 声明纯虚函数时出错
【发布时间】:2018-02-24 02:28:05
【问题描述】:

我有两个类,基类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*/
    }
}

所以在编译这段代码时,编译器会报“error LNK2001: unresolved external symbol”错误。从代码本身,我看不出我犯了任何错误。有趣的是,如果我将“ImplDefinition”从纯虚函数更改为虚函数。

void ImplDefinition() {};

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

【问题讨论】:

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


【解决方案1】:

问题是你在A::A() 中调用虚函数ImplDefinition()。在基类的构造函数中,当前对象始终是基类子对象时,派生类部分根本不构造;这将在稍后执行。然后会调用纯虚拟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?

【讨论】:

  • 非常感谢您的回答。但我真正想要的是在基类构造函数中调用接口函数(或虚函数)。或者我必须在每个派生类中编写相同的调用函数。有没有代码模板来实现这个?
  • @newcarcrazy 您不能在构造函数中执行此操作。您可以将其移至普通成员函数,或更改为整个设计,例如使类接受基类指针的实例,并在其上调用虚函数;那么你可以将任何派生类指针传递给它。
【解决方案2】:

您正试图从同一个类的构造函数中调用纯虚函数。形式上,行为是未定义的。在实践中,这样的代码最终会出现链接器错误是完全正常的。

当从构造函数或析构函数调用虚函数时,虚机制在当前层次级别被“封顶”:它“直到”被构造/析构的类工作。它永远不会看到或调用来自任何派生类的任何重写虚函数。

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

至少在这种形式下,您尝试执行的操作将行不通。您不能通过调用在派生类中重写的虚函数来“虚拟化”构造函数的行为。

【讨论】:

    猜你喜欢
    • 2020-10-19
    • 2019-07-28
    • 1970-01-01
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多