欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程语言 > c/c++ >内容正文

c/c++

这是要把前几年积累的C++的节操给丢光吗

发布时间:2024/9/30 c/c++ 42 豆豆
生活随笔 收集整理的这篇文章主要介绍了 这是要把前几年积累的C++的节操给丢光吗 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

是java把人给养废了还是c++的坑太多?


#include <iostream> #include <string> #include <vector>using namespace std;class A {public:string str;A(const string &s):str(s){}~A() {cout << "destruct A\n";}};class Base { }; class B: public Base{public:A a;vector<int> vec;B(const vector<int> &v, A &a1):vec(v), a(a1){} };int main() {//A *a = new A("hello");//delete a;vector<int> vec(100,5);A a("aaa");Base *b = new B(vec,a);delete b;return 0; }
上面的程序有问题吗?



很严重的内存泄露。

C++的多态是通过虚函数实现的,要是不把Base的析构函数设为virtual的,在delete时,就调用base的析构函数了,而不是调用B的析构,然后B中有成员变量vec就没法释放了。

解决办法很简单,就是在base中添加个virtual的析构函数就行了。


先回忆下类的构造顺序,先构造基类,再构造派生类

具体的讲就是在构造类的时候,先构造基类,在构造当前类的成员变量,最后调用当前类的构造函数


析构的时候顺序相反


看上面的程序,delete b的时候,因为Base没有virtual的析构函数,所以,只会调用Base的析构函数,而不会调用B的析构函数,因为B的成员变量是在调用B的析构函数只会再析构的,所以,B的成员变量也不会被析构


刚开始看B类,是两个非指针类型的成员变量,所以,即使没有调用B类的默认生成的析构函数,只调用Base类的析构函数,应该也不会有内存泄露。但是,要注意的是,string和vector内部实现都只是一个指针,然后向堆中申请内存,如果不调用默认生成的析构函数,那么也不会析构string和vector,造成内存泄露。


解决方案:如果有继承的话,基类一定要有虚析构函数



总结

以上是生活随笔为你收集整理的这是要把前几年积累的C++的节操给丢光吗的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。