赞
踩
根据《effective C++》第7章所述,new的一个子类对象赋值给基类指针delete的时候为了防止子类的析构函数没有调用要在基类的析构函数加上virtual 关键字:
#include <stdint.h> #include <iostream> #include <iomanip> #include <vector> class A { public: A() : a(0) { } virtual ~A() { std::cout << "delete A" << std::endl; } private: int a; }; class B : public A { public: B() : A(), b(1), c(2) {} ~B() { std::cout << "delete B" << std::endl; } private: int b; int c; // members }; int main() { A *a1 = new B; delete a1; }
成功析构!
然而根据《more effective C++》第三章所说,用一个数组存放基类的指针指向子类的对象,使用delete []来释放子类的对象会出现内存泄漏(crash):
#include <stdint.h> #include <iostream> #include <iomanip> #include <vector> class A { public: A() : a(0) { } virtual ~A() { std::cout << "delete A" << std::endl; } private: int a; }; class B : public A { public: B() : A(), b(1), c(2) {} ~B() { std::cout << "delete B" << std::endl; } private: int b; int c; // members }; int main() { A *a1 = new B[2]; delete[] a1; }
结果是什么也没有输出。
一个朴素的解决办法是不要使用new一个指针数组,改用vector或array来存放指针:
#include <stdint.h> #include <iostream> #include <iomanip> #include <vector> class A { public: A() : a(0) { } virtual ~A() { std::cout << "delete A" << std::endl; } private: int a; }; class B : public A { public: B() : A(), b(1), c(2) {} ~B() { std::cout << "delete B" << std::endl; } private: int b; int c; // members }; int main() { std::vector<A *> v; v.push_back(new B); v.push_back(new B); for (int i = 0; i < v.size(); ++i) delete v[i]; }
这样即使用一个基类指针指向子类指针也能正确地析构
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。