【问题标题】:How to use automatic reference counting and virtual functions together in the C++?如何在 C++ 中同时使用自动引用计数和虚函数?
【发布时间】:2012-06-27 16:22:59
【问题描述】:

我一直在寻找这个问题的答案。

我想在可能和必要的地方使用共享数据(shared_ptr 或类似的东西)。但我也想使用虚函数。正如您在下面看到的,它们一起使用是有矛盾的。

我以这种方式保护类的数据:

class MyObject {
public:
    void method() {
        // no memory leak here, because this contains
        // count of references of Data inside shared_ptr
        OtherObject::otherMethod(this);
    }
private:
    class Data {};
    shared_ptr<Data> data;
};

因为如果我只是将 MyObject 类嵌套在 shared_ptr 中,我将无法在某些方法中将“this”原始指针安全地传递到 MyObject 类之外。原始指针不受引用计数保护。

例子:

class MyObject {
public:
    void method() {
        // memory leak here, because this does not contain
        // count of references of Data or of self (MyObject) 
        OtherObject::otherMethod(this);
    }
private:
    class Data {};
    Data data;
};

...

shared_ptr<MyObject> crazyLeakingObject;

crazyLeakingObject 泄漏,因为它内部有 MyObject 及其所有数据和方法,但它只是 MyObject 没有任何关于引用计数的信息。在 MyObject 的方法中,我们没有这样的信息。

当我不需要虚函数时我使用的第一种方法。但第二个是针对虚拟功能的。如您所知,您只能通过现有对象的指针(原始指针)访问 vtable。但是原始指针和受保护的共享指针是相反的。 这两种方法一起使用会使我的项目架构变得混乱。 第二种方法存在漏洞。

有没有办法使用虚函数和自动引用计数?我在哪里可以找到示例?你遇到过这个问题吗?

我的母语不是英语,所以您可以要求澄清。

提前致谢。

【问题讨论】:

  • 我必须承认完全混淆了你想要达到的目标。无论如何,使用您提供的代码,没有内存泄漏。
  • shared_ptr&lt;MyObject&gt; crazyLeakingObject; 不会泄露任何东西。它甚至没有创建MyObject 的实例,只是一个空的shared_ptr。我认为您需要显示更多代码,并带有泄漏的示例。
  • 这个问题一团糟。我建议您坐下来几分钟,重新考虑真正困扰您的事情并写一个更简单的问题。有些不清楚的地方:标题提到了虚函数,但整个问题中没有其他提及。目前尚不清楚otherMethod 是什么,参数应该是什么和/或预期的行为是什么(重要的部分是它是否只使用参数或者它是否也可以存储 供以后使用,比如在成员变量中)。 crazyLeakingObject 本身并没有泄漏,你能解释一下你的意思吗?

标签: c++ garbage-collection shared-ptr virtual-functions


【解决方案1】:

可以通过shared_ptr使用虚函数:

struct Base {
    virtual ~Base() {}
    void foo() { std::cout << "base\n"; }
};

struct Derived : Base {
    void foo() { std::cout << "derived\n"; }
};

int main() {
    shared_ptr<Base> ptr(new Derived());
    ptr->foo(); // prints "derived"
} // object is deleted at function return

如果您的OtherObject::otherMethod 将它的参数存储在某个地方,这样它可以比调用者的引用持续更长时间,那么您可能会遇到问题。您可以将shared_ptr 传递给otherMethod 而不是原始指针,并使用Boost 的enable_shared_from_this 以便method 中的代码可以获得指向对象本身的共享指针,以传递给otherMethod。但是没有看到任何相关的代码,我不知道这是否有必要或一个好主意。

【讨论】:

  • 使用shared_ptr 的一个理由是您不能复制,因为对象是多态的。关于从this 生成新指针,我发现boost::invasive_ptr 在这里非常有效。
  • 这样编译会更好:-)。
  • 谢谢,我会尝试使用 enable_shared_from_this。这就是我试图自己写的。不介意它可以在 C++ 标准中。
【解决方案2】:

您想使用 std::enable_shared_from_this 来传递共享对象的 this 指针...

http://en.cppreference.com/w/cpp/memory/enable_shared_from_this/enable_shared_from_this

【讨论】:

    猜你喜欢
    • 2022-11-21
    • 2023-03-29
    • 2021-09-05
    • 2019-09-09
    • 1970-01-01
    • 1970-01-01
    • 2015-09-29
    • 1970-01-01
    • 2018-03-04
    相关资源
    最近更新 更多