我的AB.h文件中有一个构造函数:
class AB{
private: int i;
public:
AB:i(0){}//constructor
~AB:i(0){} // destructor
virtual void methodA(unsigned int value)=0;};
编译器说:
AB类具有虚函数但非虚析构函数
AB.h:在析构函数'AB :: ~AB()'中:
AC.h:错误:只有构造函数采用基本初始化器
如果我使用~AB();析构函数,它说我有虚函数但我没有析构函数,我误解了哪里? 三江源
答案 0 :(得分:9)
使用初始化列表,例如
AB : a_member(4),another_member(5) {}
只对构造函数有意义(并且是允许的) - 在析构函数中,你不想初始化东西。
除了这个明显的语法错误之外,编译器还会发出警告,因为AB
有一个virtual
方法,但也没有声明它是析构函数virtual
。建议这样做是因为:
AB* ab = new SomethingDerivedFromAB();
delete ab; // calls only AB's dtor and not SomethingDeriveFromAB's unless AB declares its dtor virtual
答案 1 :(得分:6)
您收到错误和无关的警告。
错误是因为您正在为析构函数使用初始化程序,这没有意义且语法无效。
你想:
~AB() { } // destructor
警告是因为您尚未声明析构函数是虚拟的。 Classes with virtual methods should have virtual destructors:
virtual ~AB() { }
答案 2 :(得分:2)
如果你有虚函数,那就是该类要被子类化的指示。
如果你没有将析构函数声明为虚函数,那么具有指向基类的指针的人就可以调用析构函数,因为它不是虚析构函数,所以它不会调用子类的析构函数。这样的条件会使子类管理的内存/项目处于不稳定状态,因为它们无法正常清理。
要学习的教训是始终使析构函数成为虚拟,即使您已经提供了实现。
答案 3 :(得分:1)
您应该使用virtual ~AB { }
或protected: ~AB { }
作为析构函数。
成员初始化列表: var(whatever)
用于构造对象,在析构函数中没有意义。
关于虚拟性的警告是因为一般情况下,如果您打算以多态方式使用您的类,您希望它也能够以多态方式被删除。或者使析构函数受到保护,这样就不能从父指针中多态破坏对象。
答案 4 :(得分:1)
析构函数应该是虚拟的,因为您计划继承此类(methodA是虚拟的)。但是,这只是一个警告。
错误是析构函数没有参数,显然没有初始化器。
virtual ~AB() {}
答案 5 :(得分:1)
class AB{
private: int i;
public:
AB:i(0){}
virtual ~AB(){}
virtual void methodA( unsigned int value ) = 0 ; };
答案 6 :(得分:1)
关于虚拟析构函数,请参阅Rule of Three。
答案 7 :(得分:1)
您在析构函数中缺少括号和初始化:O.o
class AB
{
private:
int i;
public:
AB():i(0){} // <-- parentheses here
virtual ~AB() {} // <-- parentheses here
virtual void methodA(unsigned int value)=0;
};
答案 8 :(得分:0)
编译器警告你,虽然你的类中有一个虚方法,但你的析构函数不是虚拟的。这可能会导致问题,因为程序中可能只会调用基础析构函数。