保存指向对象指针的类的析构函数

Destructor for class that holds pointer to object

本文关键字:析构函数 指针 对象 保存      更新时间:2023-10-16

假设我们有一个类,它保存着指向另一个对象的指针成员。如果我在析构函数中删除那个指针,就会得到一个错误(我知道为什么)。

我的问题是:有没有可能在没有内存泄漏的情况下克服这个问题?

这是我正在做的一个演示。

class A {
    public:
    ~A() { cout<< "~A()" <<endl; }
};
class B {
    A *pA;
    public:
    B(A* pA) {
        this->pA = pA;
    }
    ~B() { 
                delete pA;
        cout<<"~B()"<<endl;
    }
};
int main() {
    A a;
    {
        B b2(new A()); //deletes A, deletes B, no memory leaks
    }
    {
        B b(&a); //deletes A, error.
    }
    return 0;
}

首先,这不是内存泄漏,而是未定义行为,这是一个更严重的问题。试图从错误的区域释放内存。
只能在相应的new/new[]/malloc()上使用delete/delete[]/free()

没有完全证明和体系结构独立的方法,只是坚持良好的编程实践。

可能并不总是完美的,但一种方法是重载newdelete并保持std::map类数据结构。每当调用new时,将指针添加到它。在delete上,可以检查指针是否存在,分配类型是new还是new[]等等。
这肯定会影响您的性能,所以您需要将其保持在调试模式下。

您有两个对象,它们认为自己拥有一个动态分配的对象,并试图删除它。解决方案是决定谁应该拥有对象,并在适当的智能指针的帮助下实现正确的复制/赋值行为:

  1. AB处理动态分配的对象吗?没有办法从原始指针中知道这一点,因此必须修改设计以涵盖一种或另一种情况。假设动态对象分配,则
  2. 每个对象拥有自己的副本:在AB中实现三个规则,并且只删除两个中的一个。您可以使用作用域指针来简化内存管理(boost_scoped_ptr,或std::unique_ptr)。
  3. 唯一所有权:一个对象拥有副本:使用std::unique_ptr。禁止复制和赋值,允许移动-复制和移动-赋值
  4. 共享所有权:没有人/所有人拥有对象。当没有人引用它时,它会被删除:使用std::shared_ptr

你必须告诉B,它什么时候拥有指针,什么时候不拥有。

添加一个额外的标志,告诉当

class B {
    bool owner;
    A *pA;
    public:
    B(A* pA, bool bOwner) : owner(bOwner) {
        this->pA = pA;
    }
    ~B() { 
        if (owner)
            delete pA;
        cout<<"~B()"<<endl;
    }
};
int main() {
    A a;
    {
        B b2(new A(), true); //deletes A, destroys B, no memory leaks
    }
    {
        B b(&a, false); //destroys B, ok.
    }
    return 0;
}