黑龙江建设监理协会网站,网站建设 保密,seo如何优化网站,合肥百度快速排名优化纯虚析构的问题
多态使用时#xff0c;如果子类中有属性开辟到堆区#xff0c;那么父类指针在释放时无法调用到子类的析构代码。
解决方式#xff1a;将父类中的析构函数改为虚析构或者纯虚析构
虚析构和纯虚析构共性#xff1a;
可以解决父类指针释放子类对象都需要有…纯虚析构的问题
多态使用时如果子类中有属性开辟到堆区那么父类指针在释放时无法调用到子类的析构代码。
解决方式将父类中的析构函数改为虚析构或者纯虚析构
虚析构和纯虚析构共性
可以解决父类指针释放子类对象都需要有具体的函数实现
虚析构和纯虚析构区别
如果是纯虚析构该类属于抽象类无法实例化对象
虚析构语法
virtual ~类名(){}
纯虚析构语法 virtual ~类名() 0;
类名::~类名(){}
示例
class Animal {
public:Animal(){cout Animal 构造函数调用 endl;}virtual void Speak() 0;//析构函数加上virtual关键字变成虚析构函数//virtual ~Animal()//{// cout Animal虚析构函数调用 endl;//}virtual ~Animal() 0;
};Animal::~Animal()
{cout Animal 纯虚析构函数调用 endl;
}//和包含普通纯虚函数的类一样包含了纯虚析构函数的类也是一个抽象类。不能够被实例化。class Cat : public Animal {
public:Cat(string name){cout Cat构造函数调用 endl;m_Name new string(name);}virtual void Speak(){cout *m_Name 小猫在说话! endl;}~Cat(){cout Cat析构函数调用! endl;if (this-m_Name ! NULL) {delete m_Name;m_Name NULL;}}public:string *m_Name;
};void test01()
{Animal *animal new Cat(Tom);animal-Speak();//通过父类指针去释放会导致子类对象可能清理不干净造成内存泄漏//怎么解决给基类增加一个虚析构函数//虚析构函数就是用来解决通过父类指针释放子类对象delete animal;
}int main() {test01();system(pause);return 0;
}注意即使是纯虚析构也需要有具体的实现。因为包含纯虚函数的类为抽象类被继承后在派生类析构函数被调用时抽象类析构函数也将被调用因此必须有实现。唯一麻烦就是必须在类的定义之外cpp文件实现它。
总结
1. 虚析构或纯虚析构就是用来解决通过父类指针释放子类对象
2. 如果子类中没有堆区数据可以不写为虚析构或纯虚析构
3. 拥有纯虚析构函数的类也属于抽象类 纯虚函数的实现案例纯虚析构函数必须有实现
纯虚函数可以有实现唯一麻烦就是必须在类的定义之外cpp文件实现它。 申明一个函数为纯虚并不意味着它没有实现它意味着
当前类是抽象类 任何从此类派生的实体类必须将此函数申明为一个“普通”的虚函数也就是说 不能带“ 0”。
1、纯虚函数例子
声明一个pure virtual 函数的目的是为了让 derived classes 只继承函数接口派生类必须提供实现。 可以为pure virtual函数提供实现但使用时需要指明所属类如
//.h
class A{
public:virtual void func1() 0;
};
class B : public A{
public:virtual void func1(){A::func1();};
};//.cpp
void A::func1(){..........}B b;
b.A::func1(); // 与b.func1()结果相同相当于提供了缺省实现但派生类需要主动指定。2、纯虚析构函数必须有实现
因为包含纯虚函数的类为抽象类被继承后在派生类析构函数被调用时抽象类析构函数也将被调用因此必须有实现。
class A{
public:virtual ~A() 0;
};//.cpp
A::~A(){...}总结 1、纯虚函数可以有实现但必须在类的定义之外cpp文件实现。 2、纯虚析构函数必须有实现。 参考链接 纯虚函数的实现案例纯虚析构函数必须有实现