【问题标题】:C++: Exposing pointers to class with managed memoryC ++:使用托管内存公开指向类的指针
【发布时间】:2015-10-20 12:18:11
【问题描述】:

我有以下设置:

class Foo {
public:
    Foo() {}

    vector<BigObject*> mPointers;
};
class Bar {
public:
    Foo *exposeSomeFoo() { return &mFoos[42]; }
private:
    vector<Foo> mFoos;
    vector<BigObject> mMemoryManaged;
};

我基本上是在尝试确保在我的代码中任何时候都不会有人意外使用 Foo ,因为它所暴露的 Bar 已超出范围。

但这显然是有问题的。如果我像上面那样公开指向Foo 的指针,一旦Bar 超出范围,它们就会变得无效。如果我改为使用Foo exposeSomeFoo(),那么一旦Bar 超出范围,mPointers 也会变得无效 - 如果mPointers 有很多元素,返回副本似乎是个坏主意!

我已经尝试通过创建一个私有复制构造函数来解决这个问题:

class Foo {
public:
    Foo() {}

    vector<BigObject*> mPointers;
private:
    Foo(const Foo&);
};

但是当我尝试从Bar 中将Foo 插入mFoos 时出现错误。

必须有一个范式,在允许完全内存安全的同时仍然允许我公开这样的功能。如何将来自Bar 的复合对象公开给其他地方的代码,其内存由Bar 或至少在编译单元本身专门管理?

【问题讨论】:

  • 可以使用shared_ptr的向量

标签: c++ pointers memory scope


【解决方案1】:

如果您想确保您的所有对象都可以共享资源,这样只要所有对象都存在,资源就处于活动状态,只需在任何地方使用std::shared_ptr

class Foo {
public:
    Foo() {}

    vector<shared_ptr<BigObject>> mPointers;
};

class Bar {
public:
    shared_ptr<Foo> exposeSomeFoo() { return mFoos[42]; }
private:
    vector<shared_ptr<Foo>> mFoos;
    vector<shared_ptr<BigObject>> mMemoryManaged;
};

这样,调用者可以毫无顾虑地保留bar.exposeSomeFoo() - 调用者现在共享它的所有权,所以他的将是完全安全的。

【讨论】:

  • 非常好,谢谢!一个问题。假设客户正在定义void function(Bar &amp;bar) { ... }。当然,客户 100% 确定 Bar 仍然存在。在这个定义中将shared_ptr“折叠”成一个简单的Foo* 是不好的做法,在这种情况下该怎么做?
  • @bombax 为什么?只需使用shared_ptr
  • 我只是关心模块化(我感觉很多程序员都用 typedef 之类的东西来做这件事?)
【解决方案2】:

实际上,我最终做了这样的事情:

class Foo {
public:
    Foo(shared_ptr<vector<BigObject> > bigObjects) : mBigObjects(bigObjects) {

    }
private:
    vector<BigObject*> mPointers;
    shared_ptr<vector<BigObject> > mBigObjects;
};

class Bar {
public:
    Bar() {
        mBigObjects = shared_ptr<vector<BigObject> >(new vector<BigObject>);
        for (int i = 0; i < 100; i++)
            mBigObjects->push_back(BigObject());
        for (int i = 0; i < 100; i++)
            mFoos.push_back(Foo(mBigObjects));
    }
    Foo exposeSomeFoo() { return mFoos[42]; }
private:
    shared_ptr<vector<BigObject> > mBigObjects;
    vector<Foo> mFoos;
};

我认为这是我想要的行为:只有当 FooBar 的所有实例都被销毁时,带有 BigObjects 的向量才会真正被销毁。有人可以仔细检查这是安全且良好的做法吗?谢谢!

【讨论】:

    猜你喜欢
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    相关资源
    最近更新 更多