【问题标题】:shared data between objects via a pointer in C++通过 C++ 中的指针在对象之间共享数据
【发布时间】:2011-06-21 21:42:16
【问题描述】:

我有几个对象通过指针共享数据。指针参数通过构造函数发送,如下所示。

class A
{
public:
    Shared* pB = new Shared();
    User* object1 = new User(pB);
    User* object2 = new User(pB);
}

class User
{
public:
    User(Shared* pB) {m_sharedB = pB};
private:
    Shared* m_sharedB;
}
class Shared
{
public:
    struct Account 
    {
        int account_number;
    }
    void method(){...};
}

我的问题与 C++ 析构函数有关。当 object1 被删除时,成员变量“m_sharedB”会发生什么?是否存在其他对等点悬空指针的问题?

【问题讨论】:

  • 大量错误。你真的自己尝试过什么吗?请修复基本语法错误。
  • Shared 指向你的班级吗?还是库类?
  • m_sharedB 指向的对象不会被删除。曾经。我不知何故认为这不是您要寻找的答案。也许您应该问的问题是如何在不再需要该对象后立即销毁它?
  • Shared 不是库类,它只是一个普通类

标签: c++ constructor destructor shared-ptr


【解决方案1】:

如果你有一个类包含一个指针成员,

class Foo
{
  Bar * mp_bar;
};

然后在销毁 Foo 对象时,除了指针及其包含的对象超出范围之外,什么都不会发生。这与以下函数末尾p 发生的情况相同:

void bar()
{
  int * p;
}

您可能想问的是“指针指向的对象会发生什么”。这是一个完全不同的问题,答案是“没有”。

(所以通常当你有一个包含指针成员的类时,你应该仔细考虑谁拥有可能需要清理的任何资源。)


既然你在你的问题中提到了“析构函数”这个词,让我们一劳永逸地拼出来:

指针类型对象没有析构函数。当指针超出范围时,不会自动调用delete

【讨论】:

  • @user481034:嗯,当Foo 类型的对象位于堆栈上并超出范围时,其成员对象也会超出范围并展开。如果Foo 对象已在堆上分配,那么当Foo 分配时,其成员对象将被释放。
  • 这个成员变量指针的行为是否像堆栈上的局部变量或临时变量一样,一旦函数返回,它们就从堆栈内存中展开。另外,您是否建议指针所有者或创建者(即 A 类)应该删除指针?那么如果在非所有者,即用户类的 dtor 中,m_shared 被删除了怎么办?
  • @user481034:这个问题一般无法回答,这真的取决于你的设计。您必须考虑指针来自哪里以及它是否指向堆分配的资源。原则上是的,最终必须有人释放内存。通常会创建在构造函数中分配内存并在析构函数中释放内存的内存管理类,但是您必须非常小心地复制这样的对象。请参阅shared_ptr 了解如何正确操作。然后使用shared_ptr ;-)
  • 是否有任何资源或书籍根据 ctor 和 dtor 的内存操作解释 C++ 数据模型?
  • @user481034:构造函数和析构函数与“内存操作”无关。它们只是分别在实例化和超出范围(自动变量)或释放(即delete 用于堆变量)时自动调用的函数。不确定书籍,我认为 Stroustrup 的原著解释了该语言非常好且可读性强。 [更新] 好的,通过递归构造成员对象,构造实际上做得更多,但尽管如此,这是与内存管理正交的概念。
【解决方案2】:

破坏原始指针变量是无操作的 (read more)。共享对象仍然可用。

【讨论】:

    【解决方案3】:

    当 object1 被删除时,m_sharedB 指向的内存将不会被释放,因为你没有为类 User 提供析构函数。这也留给包含类(A 类)来管理 Shared 指针的生命周期,确保一旦不再存在对它的引用,它就会被正确删除(即,共享相同 Shared 指针的所有 User 实例都是死了)。

    【讨论】:

    • 你没有提供析构函数。自动生成的析构函数呢?
    • 自动生成的析构函数不会删除指针。
    【解决方案4】:

    当object1被删除时,成员变量“m_sharedB”会发生什么?

    当 object1 被删除时,指针 pB 没有任何动作。但是变量 m_shared 被破坏了。 另外我想建议您使用 boost 库中的智能指针。特别是shared_ptr

    【讨论】:

    • 或 std::tr1::shared_ptr,如果有的话。
    【解决方案5】:

    听起来您的问题已得到解答,但我只想提及boost::shared_ptr。这可能无法满足您当前的需求,但在您上面描述的情况下很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-11
      相关资源
      最近更新 更多