C++ 如何解决删除在其他对象之间共享的对象的问题

C++ 如何解决删除在其他对象之间共享的对象的问题,c++,memory-management,C++,Memory Management,我有这样一个场景: struct B { A * ptr; } A * a1 = new A1; b1.ptr = a1 b2.ptr = a1 b3.ptr = a2 现在我在不同的地方删除a1,但是没有关于b对象的信息。如何自动设置: b1.ptr = null b2.ptr = null 或者这个机制是如何调用的,这样我就可以在谷歌上搜索更多信息。编辑:意外错误想法被删除 您的根本问题似乎是所有权: 您的B结构不拥有您在其他点创建的A对象,因此它不知道A对象的删除 在

我有这样一个场景:

struct B 
{ 
   A * ptr; 
}

A * a1 = new A1;

b1.ptr = a1
b2.ptr = a1
b3.ptr = a2
现在我在不同的地方删除a1,但是没有关于b对象的信息。如何自动设置:

b1.ptr = null 
b2.ptr = null

或者这个机制是如何调用的,这样我就可以在谷歌上搜索更多信息。

编辑:意外错误想法被删除

您的根本问题似乎是所有权:

您的B结构不拥有您在其他点创建的A对象,因此它不知道A对象的删除

在C++中,您可以使用共享指针:

struct B{
    std::weak_ptr<A> ptr;
}
std::shared_ptr<A> object = std::make_shared<A>();
B.ptr = object;
这将阻止在取消分配共享指针时使用对象,使其失去引用

没有简单的方法通知结构B底层数据已被删除,因为指针只是存储对象分配位置的数字。这个数字不知道对象会发生什么

最后,最后一个选项是使用某种notify方法通知所有B对象某个a对象已被删除,尽管这需要进行大量的返工,而且这并不是最好的解决方案


我希望它能有所帮助:

这基本上是上一个示例的副本。它将共享指针分配给B.ptr和更高版本的检查(如果它们仍然有效)。请注意,此代码没有将任何ptr设置为NULL。还要注意,标准智能指针需要一个提供C++11的编译器

#include <iostream>
#include <memory>

struct A {};

struct B {
    std::weak_ptr<A> ptr;
};

int main(int argc, char **argv)
{
    B b1, b2, b3;

    {
        std::shared_ptr<A> a1{new A()};
        std::shared_ptr<A> a2{new A()};

        b1.ptr = a1;
        b2.ptr = a1;
        b3.ptr = a2;
    }

    // a1 and a2 don't exist anymore

    auto tmp = b1.ptr.lock();
    if (tmp) {
        std::cout << "Ok to use\n";
    } else {
        std::cout << "Already deleted\n";
    }

    return 0;
}

我不知道是否有任何现有类在做您想要的事情,但请寻找智能指针,例如,可能弱的ptr符合您的目的。@OlafDietsche您能提供一个示例代码吗?@MartinPerry-为什么不看看这个示例,为我们展示一个有效的示例。你发布的内容甚至不可编译。
#include <iostream>
#include <memory>

struct A {};

struct B {
    std::weak_ptr<A> ptr;
};

int main(int argc, char **argv)
{
    B b1, b2, b3;

    {
        std::shared_ptr<A> a1{new A()};
        std::shared_ptr<A> a2{new A()};

        b1.ptr = a1;
        b2.ptr = a1;
        b3.ptr = a2;
    }

    // a1 and a2 don't exist anymore

    auto tmp = b1.ptr.lock();
    if (tmp) {
        std::cout << "Ok to use\n";
    } else {
        std::cout << "Already deleted\n";
    }

    return 0;
}