如何使用引用、避免标头膨胀并延迟初始化?
我正在浏览使用这么多共享指针的替代方案,并在评论部分找到了一个很好的回复:
您真的需要共享所有权吗? 如果你停下来思考一些 分钟,我相信你能指出其中一个 对象的所有者,以及一些 它的用户,只会使用 它在所有者的一生中。所以 只需将其设为本地/成员对象 的所有者,并传递引用 那些需要使用它的人。
我很乐意这样做,但问题是拥有对象的定义现在需要首先完全定义拥有的对象。例如,假设我在 FooManager.h 中有以下内容:
class Foo;
class FooManager
{
shared_ptr<Foo> foo;
shared_ptr<Foo> getFoo() { return foo; }
};
现在,按照上面的建议,FooManager.h 变为:
#include "Foo.h"
class FooManager
{
Foo foo;
Foo& getFoo() { return foo; }
};
我对此有两个问题。首先,FooManager.h 不再是轻量级的。现在包含它的每个 cpp 文件也需要编译 Foo.h。其次,我不再可以选择 foo 何时初始化。它必须与 FooManager 同时初始化。我该如何解决这些问题?
I was browsing for an alternative to using so many shared_ptrs, and found an excellent reply in a comment section:
Do you really need shared ownership?
If you stop and think for a few
minutes, I'm sure you can pinpoint one
owner of the object, and a number of
users of it, that will only ever use
it during the owner's lifetime. So
simply make it a local/member object
of the owners, and pass references to
those who need to use it.
I would love to do this, but the problem becomes that the definition of the owning object now needs the owned object to be fully defined first. For example, say I have the following in FooManager.h:
class Foo;
class FooManager
{
shared_ptr<Foo> foo;
shared_ptr<Foo> getFoo() { return foo; }
};
Now, taking the advice above, FooManager.h becomes:
#include "Foo.h"
class FooManager
{
Foo foo;
Foo& getFoo() { return foo; }
};
I have two issues with this. First, FooManager.h is no longer lightweight. Every cpp file that includes it now needs to compile Foo.h as well. Second, I no longer get to choose when foo is initialized. It must be initialized simultaneously with FooManager. How do I get around these issues?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用
shared_ptr
(或任何智能指针,甚至是哑指针),但不具有共享所有权。例如
(这只是一个草图 - 您仍然需要一个 setFoo(),也许 getFoo() 应该返回一个 Foo *。但重点是您又回到了轻量级,并且您可以控制何时创建 foo。)
You can use a
shared_ptr
( or any smart pointer, or even a dumb pointer) but not have shared ownership.E.g.
(This is just a sketch - you still need a setFoo(), and perhaps getFoo() should return a Foo *. But the point is that you're back to being lightweight, and you can control when foo is created.)
如果您不需要
shared_ptr
的共享所有权语义,请考虑使用不同的智能指针容器。根据您给出的示例(一个拥有所有权且没有所有权转让的对象),boost::scoped_ptr 将是一个不错的选择。
如果您不想使用 Boost,
scoped_ptr
非常容易实现——Boost 文档对其进行了详细描述,并且其实现(在 boost/shared_ptr.hpp 中)也很简单。If you don't need the shared ownership semantics of
shared_ptr
, consider using a different smart pointer container.With the example you give (one object having ownership and no transferral of ownership),
boost::scoped_ptr
would be a good choice.If you don't want to use Boost,
scoped_ptr
is very easy to implement--it's well described in the Boost documentation and its implementation (in boost/shared_ptr.hpp) is straightforward.使用 pimpl 习惯用法,并停止过多的内联。
FooManager.h:
FooManager.cpp
由于您已经在使用 boost,我建议您使用
scoped_ptr
在实际代码中实现此功能,而不是像我在本示例中所做的那样手动管理内存。需要记住的重要一点是,前向声明对于引用的作用与对于指针的作用一样好(这是它适用于shared_ptr
的部分原因)。Use the pimpl idiom, and stop inlining so much.
FooManager.h:
FooManager.cpp
Since you're already using boost I would recommend you use
scoped_ptr
to implement this in your real code instead of manually managing the memory as I've done in this example. The important thing to keep in mind is forward declaring works just as well for references as it does for pointers (which is part of the reason it worked forshared_ptr
).