为什么我们应该在这种情况下实现纯虚函数?

时间:2013-08-07 12:28:49

标签: c++

我的代码:

class A
{
public:
    A(){}
    A(int _a) : a(_a){}
    virtual ~A() = 0;
private:
    int a;
};


class B : public A
{
public:
    B(){}
    B(int _a):A(_a){}
    ~B(){}
private:
};

我声明B b;,然后当我编译这个程序时,我遇到了这个错误:

error LNK2019: unresolved external symbol "public: virtual __thiscall A::~A(void)" (??1A@@UAE@XZ) referenced in function "public: virtual __thiscall B::~B(void)" (??1B@@UAE@XZ)

我想知道,我们是否需要始终实现纯虚函数?

4 个答案:

答案 0 :(得分:9)

通常,您不需要实现纯虚函数。确实这就是重点。但是,使用析构函数,因为析构函数不能接受实现。这是因为与常规虚拟方法不同,在运行时只使用派生最多的虚拟方法,从最大到最小的派生中调用继承链中的所有虚拟析构函数,以便派生对象的所有字段都可以被妥善摧毁。

由于这个原因,最好不要使纯虚拟析构函数变为纯粹,除非在必要的情况下(例如,当你有一个必须是抽象的基类但没有其他虚拟方法可以变为纯粹的基类时)。

答案 1 :(得分:1)

应该在调用时实现它。否则没有。 纯虚拟意味着包含它的类的实例coudn t be created, not that method coudn被调用,没有什么阻止你在这种情况下从派生类调用纯虚方法 - 需要实现

Upd:在你的情况下,由于调用了基类的析构函数 - 需要实现,请参阅上面的解释。

答案 2 :(得分:1)

如果调用纯虚函数,则必须实现它。所以,例如:

struct A {
    virtual void f() = 0;
};

struct B : A {
    void f();
};

void B::f() { std::cout << "B::f called\n"; }

但是,如果B::f拨打A::f,则必须实施A::f

void B::f() { A::f(); std::cout << "B::f called\n"; }

B::f的定义,还必须有A::f的定义。

与虚拟析构函数相同:如果调用它,则必须实现它。析构函数的不同之处在于,基类中的析构函数始终由派生类的析构函数调用,因此您必须始终实现纯虚拟析构函数。即使它没有做任何事情。

答案 3 :(得分:0)

根据定义,纯虚函数是一个需要始终在继承对象中定义的虚函数。所以答案是肯定的,你有。如果你真的不需要它,你可以定义一个没有代码的函数。