在多态性中调用3层析构函数
Calling 3 layers of destructors in polymorphism
我真的陷入了这个问题。我有一个内存泄漏的应用程序。为了解决这个问题,我需要调用类的析构函数。
对于2层类,这个问题很简单,但在这种情况下,有3层类,我找不到任何方法来编译:
#include<iostream>
using namespace std;
/* *MUST* be an abstract class and contains data that must be freed */
class C {
public:
virtual ~C()=0;
};
/* Contains concrete methods and contains data that has to be freed */
class B:public C {
public:
virtual ~B();
};
/* contains no data, only methods nothing needs to be freed in here */
class A:public B {
public:
~A();
};
int main(){
C *c = new A;
return 0;
}
当我编译代码时,我得到错误:
martyn@Hades ~ $ gcc deleteme.cpp -std=c++11
/tmp/cc7nxaw5.o: In function `main':
deleteme.cpp:(.text+0x12): undefined reference to `operator new(unsigned int)'
/tmp/cc7nxaw5.o: In function `__static_initialization_and_destruction_0(int, int)':
deleteme.cpp:(.text+0x4b): undefined reference to `std::ios_base::Init::Init()'
deleteme.cpp:(.text+0x62): undefined reference to `std::ios_base::Init::~Init()'
/tmp/cc7nxaw5.o: In function `B::B()':
deleteme.cpp:(.text._ZN1BC2Ev[_ZN1BC5Ev]+0x16): undefined reference to `vtable for B'
/tmp/cc7nxaw5.o: In function `A::A()':
deleteme.cpp:(.text._ZN1AC2Ev[_ZN1AC5Ev]+0x16): undefined reference to `vtable for A'
/tmp/cc7nxaw5.o:(.rodata._ZTV1C[_ZTV1C]+0x8): undefined reference to `__cxa_pure_virtual'
/tmp/cc7nxaw5.o:(.rodata._ZTV1C[_ZTV1C]+0xc): undefined reference to `__cxa_pure_virtual'
/tmp/cc7nxaw5.o:(.rodata._ZTI1C[_ZTI1C]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
collect2: error: ld returned 1 exit status
有人能想出一种方法,我可以重写析构函数,这样a、B和C的析构函数都被调用吗?
我用这个把头发都扯掉了,任何帮助都将不胜感激。但是,我不能更改注释或继承层次结构中的要求,这样做需要重写整个应用程序。
非常感谢。
编辑:非常感谢您对以下问题的评论,对我有效的解决方案是:
#include<iostream>
using namespace std;
/* *MUST* be an abstract class and contains data that must be freed */
class C {
public:
virtual ~C()=0;
};
C::~C(){
cout<<"destroying C"<<endl;
}
/* Contains concrete methods and contains data that have to be freed */
class B:public C {
public:
~B();
};
B::~B(){
cout<<"destroying B"<<endl;
}
/* contains no data, only methods nothing needs to be freed in here */
class A:public B {
public:
~A();
};
A::~A(){
cout<<"destroying A"<<endl;
}
int main(){
C *c = new A;
delete c;
return 0;
}
非常感谢你的建议。
这里的解决方案是在需要析构函数的类中实现析构函数,并让编译器处理其余的。
首先,C有一些数据需要释放,所以C得到了这样的析构函数:
class C{
int* cp;
public:
C(){ cp = new int;}
virtual ~C(){
delete cp;
cout << "~C()" << endl;
}
virtual void someMethod()=0;
};
类B应该实现纯虚拟函数,并且有需要释放的数据,所以:
class B: public C{
int* bp;
public:
B(){ bp = new int;}
virtual ~B(){
delete bp;
cout << "~B()" << endl;
}
virtual void someMethod(){//some Implementation
}
};
最后,类A只提供了一些方法,所以我们不需要析构函数。但我也会在这里包括一个演示:
class A: public B{
public:
virtual ~A(){
cout << "~A()" << endl;
}
};
构造这个类并用delete
调用析构函数将正确地调用所有三个析构函数:
int main(){
C *c = new A;
delete c;
return 0;
}
输出:
~A()
~B()
~C()
在线试用
请注意:在您发布的代码中,您似乎试图使用纯虚拟析构函数的声明来使类抽象。但是,如果你必须释放类中的资源,那么你需要使用另一个函数来实现这个目的,如果你没有一个纯虚拟函数的话。
编辑:
阅读这里可以了解到,为同一函数提供纯说明符和定义确实是有效的,这也适用于析构函数。所以你确实可以做到这一点:
class C{
virtual ~C() = 0;
};
C::~C(){ /*Implementation here*/}
最后,只要至少有一个函数是纯虚拟的(=0
),那么类就是抽象的。如果这是析构函数或其他函数,则无关紧要。但是,如果您的类需要释放资源,则需要为析构函数提供一个主体。
相关文章:
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- C++ 防止在映射中放置()时调用析构函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 调用析构函数以释放动态分配的内存
- 在多态性中调用3层析构函数