【问题标题】:C ++ abstract base class templatesC++ 抽象基类模板
【发布时间】:2011-06-12 17:19:45
【问题描述】:

这段代码有什么问题?

template <class T>
class A
{
private:
    T a;

public:
    A(): a(0) {}
    virtual ~ A() = 0;
};


template <class T>
class A;

template <class T>
class B : public A<T>
{
private :
    T b;

public:
    B() : A<T>() {}
    virtual ~B(){}


};


int _tmain(int argc, _TCHAR* argv[])
{
B <double> bb;
return 0;
}

错误 LNK2019:未解析的外部符号“public: virtual __thiscall A::~A(void)”(??1?$A@N@@UAE@XZ) 在函数“public: virtual __thiscall B::~”中引用B(void)" (??1?$B@N@@UAE@XZ)

【问题讨论】:

    标签: c++ templates abstract-class


    【解决方案1】:

    您将A 的析构函数声明为纯虚函数。这一切都很好,如果你想保证类永远不会被实例化,这可以被认为是一种很好的做法。但是,您仍然必须在代码中的某处定义A::~A(),因为B 的析构函数自动调用B 对象上的A::~A()。由于您声明它是纯虚拟的,因此您不能像使用 ~B 那样内联定义它;您必须在类定义之外包含它的定义。

    【讨论】:

    • 我相信它可以在VC++中内联实现。 (这不是可移植的,但_tmain(int, _TCHAR *[]) 也不是。)
    • 我相信您在 GCC 中也可以。但是,我想说的是,您不能将其声明为纯虚拟并同时内联实现它(除非您在类定义之后内联实现它)。
    【解决方案2】:

    您需要为基类析构函数提供实现。即使析构函数被声明为纯虚函数,也需要实现来销毁派生类。

    【讨论】:

    • 喜欢吗? :template A::~A() {}
    【解决方案3】:

    你的超类析构函数不应该是纯虚的,只是虚的。

    virtual ~A() {}
    

    B的析构函数会自动尝试调用A的析构函数。

    【讨论】:

    • 你应该添加析构函数的定义,因为当你让B从类A继承来构建B的析构函数时编译器需要它。定义析构函数A纯虚拟被大多数人认为是最佳实践。
    猜你喜欢
    • 2021-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-25
    • 2017-09-28
    • 2010-12-02
    相关资源
    最近更新 更多