cpp中的析构函数会自动调用吗?即使析构函数没有提及非动态变量,它们是不是也会被删除?

Posted

技术标签:

【中文标题】cpp中的析构函数会自动调用吗?即使析构函数没有提及非动态变量,它们是不是也会被删除?【英文标题】:Is a destructor in cpp called automatically? And are non dynamic variables removed even when the destructor doesn't mention them?cpp中的析构函数会自动调用吗?即使析构函数没有提及非动态变量,它们是否也会被删除? 【发布时间】:2018-06-29 23:10:11 【问题描述】:

鉴于以下代码,我会不会有内存泄漏?

class B 
    int x;


class A 
    int x;
    int y;
    B* tab[10];
    A(int x, int y)
        this->x = x;
        this->y = y;
        for (int i = 0; i < 10; i++)
            tab[i] = new B;
                    
    
    ~A()
        for (int i = 0; i < 10; i++)
            delete tab[i];
        
    
int main()
    A a(10, 10);
    return 0;

据我了解,指向 B 类的指针不会导致内存泄漏,但我担心我会通过覆盖默认析构函数行为导致一些意外泄漏,难道不会有内存泄漏来自int x 和 int y 因为我的析构函数完全省略了它们?

【问题讨论】:

您在main 中发布的内容之外存在问题。如果main 这样做 A a(10,10); A a2 = a; -- 那么 你会遇到问题,因为析构函数会删除相同的指针两次。 我明白,我必须编写一个复制构造函数,但是在我正在处理的项目中,A 类对象只创建一次,所以这不是问题。 我正在处理的 A 类对象只创建一次 -- 编译器可以在您不知道已创建副本的情况下进行复制。除非您使用= delete 或进行复制/分配private 明确关闭复制,否则您不能保证只复制一份。 始终遵循 3/5/0 的规则 因此,如果编译器在我不知情的情况下创建了 A 类对象,它会在运行时删除该副本时删除我指向选项卡中 B 对象的所有指针? 【参考方案1】:

据我了解,指向 B 类的指针不会导致内存泄漏

你说得对。

但我担心我会通过覆盖默认析构函数行为导致一些意外泄漏

你不应该害怕。默认析构函数不能很好地处理指针。你的实现很好。

由于我的析构函数完全忽略了 int x 和 int y,难道不会有内存泄漏吗?

原语的内存泄漏?不,int 不能泄漏。 int* 可以,但不是普通的、好的、旧的int。其他非指针类型也是如此。不是newed、malloced 等的东西不要泄漏,也不需要对应deletefrees

【讨论】:

【参考方案2】:

不会有内存泄漏,因为您没有使用new 运算符来动态分配内存。相反,它将使用堆栈,并且在main 函数的末尾它将破坏您的对象。

【讨论】:

我确实在 A 的构造函数中使用了 new。 main 中,您没有使用new 运算符来满足A 类,这很重要,因为您正在放置A 类的堆栈实例。并且由于A有析构函数,它会在程序执行即将退出main函数时清理所有实例B

以上是关于cpp中的析构函数会自动调用吗?即使析构函数没有提及非动态变量,它们是不是也会被删除?的主要内容,如果未能解决你的问题,请参考以下文章

C++中,子类会继承父类的虚函数表!对于父类的析构函数(虚函数) 也会继承吗?

为啥C++里面,析构函数会被调用两次

C# 使用 AWS lambda 时,我可以确定函数中的析构函数会被执行吗?

返回一个对象会调用它的析构函数吗?

C++ 设置基类的析构函数为虚函数

为啥自动对象的析构函数被调用两次?