我有一个关于在冗长模板中使用 typedef 的问题。症结:我发现自己陷入了困境——除了客户端函数的本地之外,似乎没有放置 typedef 的好地方。虽然有类似的 SO 问题(例如,参见 here),但似乎没有一个能够准确地解决这个问题。请注意,这个问题并没有说明 typedef 在下面的内容中是否是可取的——为了说明的目的,我试图简化一些事情。
我在使用 boost::shared_ptr<T>
时出现了问题.基本上,我想做以下事情:
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr<Widget> WidgetPtr;
将此 typedef 放在 Widget
中声明标题看起来很难看。这里似乎有两个考虑:(i) 如果 Widget
它本身没有在其成员中使用共享指针,我们添加了一个额外的包含(因为我们不能转发声明 boost::shared_ptr
模板类——如果我错了,请纠正我?)(ii)如果我们想要为了在另一个类的声明期间使用这个 typedef(调用那个类 Foo
),我们违反了最佳实践,包括 Widget.h
而不是简单地向前声明 Widget
或包括 WidgetFwd.h
...除非此 typedef 在后者中重复。此外,typedef boost::shared_ptr<Widget>
似乎没有意义。在 Widget
的声明中本身——我们似乎在混合Widget
的声明,预期客户将如何使用 Widget
界面。
好的,这很糟糕,但更糟糕的是:如果我不尝试以上的某种组合,我最终会在客户端代码中出现重复的 typedef,这会产生不一致(因此很可能是错误)——重点是给定的Widget
, 一个 WidgetPtr
typedef 本身应该作为一种类型。示例:我们不想要 Foo
使用一个WidgetPtr
,类型定义为 boost::shared_ptr
, 而 Bar
使用 WidgetPtr 作为 std::auto_ptr
的类型定义.
另一种方法(也是我在在线讨论中看到的少数几种方法之一)是使 typedef 成为 Widget
的公共(public)成员。然后使用 Widget::Ptr
:
class Widget {
// ...
public:
typedef boost::shared_ptr<Widget> Ptr;
};
同样,我不喜欢这样,因为 (i) 它暗示指针类型在某种程度上是类的成员,并且 (ii) 它导致了一个不稳定的接口(interface)。更糟糕的是:由于我编写的每个类都可能使用智能指针指向,所以我最终会追逐想象中的客户的尾部。丑,丑,丑。
就目前而言,我已经从这个代码库中删除了 typedef(因为它们会导致严重的混淆和重复),并在选定的函数中重新在本地引入它们。这里再次存在使用不一致的问题,但没有那么严重。
我能想到的唯一其他解决方案——同样我不确定这是否被认为是好的做法——将有一个实用程序头,其中放置 typedef,可能在它们自己的命名空间中。在这个标题中,我们将包含并完成它。
我是否遗漏了一些明显的东西,或者这只是简单的棘手?
PS——对以上篇幅表示歉意;我找不到更简单的方式来充分表达这个问题。
最佳答案
Furthermore, it doesn't seem make sense to typedef boost::shared_ptr during the declaration of Widget itself—we seem to be mixing Widget's declaration with an anticipation of how clients will make use of the Widget interface.
首先,这并没有错——毕竟,客户端将(并且可以)使用接口(interface)的方式是接口(interface)本身的一部分;对于 C++,对象的内存管理不是垃圾收集,是其接口(interface)中相当重要的部分。
所以有两种情况。在一种情况下,Widget
预计它将通过共享指针使用。这意味着例如。从小部件获得的子小部件以 shared_ptr
的形式返回,创建的每个小部件都有它 shared_ptr
等等。在与 Widget
相同的 header 中 typedef WidgetPtr
是完全合法的。
在第二种情况下,Widget
会被管理,例如。通过普通的 new
和 delete
。客户端可以在特殊情况下使用 shared_ptr
s,但没有任何说明。打印机对话例程不能使用 auto_ptr
代替。客户端必须做好准备,如果 wptr
是 shared_ptr
,则该行
shared_ptr<Widget> w2(wptr->firstChild()->parent());
导致灾难。
您的问题似乎表明后者是您的情况。所以恕我直言,你所做的一切都很好。客户端可以选择管理 Widget
对象的方式,只要不影响其他客户端即可。
关于c++ - typedef 共享指针的最佳策略是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4429417/