Mar*_*arc 20 c++ boost typedef shared-ptr
我有一个关于使用typedef进行冗长模板的快速问题.关键点:我发现自己处于一种腌制状态 - 似乎没有一个将typedef放在除客户端函数本地之外的好地方.虽然有类似的SO问题(例如参见这里),但似乎没有人能够解决这个问题.请注意,这个问题并没有解决下面的typedef是否可取的问题 - 我试图简化出于说明目的.
与我一起工作时出现了我的问题boost::shared_ptr<T>
.基本上,我想做以下事情:
#include <boost/shared_ptr.hpp>
typedef boost::shared_ptr<Widget> WidgetPtr;
Run Code Online (Sandbox Code Playgroud)
将此typedef放在Widget
声明头中似乎很难看.这里似乎有两个注意事项:(i)如果Widget
它本身没有在其成员中使用共享指针,我们添加了一个额外的include(因为我们无法转发声明boost::shared_ptr
模板类 - 如果我是正确的我错误?)(ii)如果我们想在声明另一个类(称为该类Foo
)期间使用此typedef,我们通过包括Widget.h
而不是简单地向前声明Widget
或包括WidgetFwd.h
...... 来违反最佳实践...除非后者重复此类型的def .此外,boost::shared_ptr<Widget>
在声明Widget
自己的过程中输入deff似乎没有意义- 我们似乎在混合Widget
声明,期待客户如何利用Widget
接口.
好吧,所以这很糟糕,但这更糟糕:如果我不尝试上面的某些组合,我最终会在客户端代码中出现重复的typedef,这会产生不一致(因此,可能是错误) - 整个点就是给定的Widget
,WidgetPtr
typedef本身应该作为一种类型.示例:我们不想Foo
使用WidgetPtr
一个typedef boost::shared_ptr
,而Bar
使用WidgetPtr作为typedef std::auto_ptr
.
另一种方法(以及我在网上讨论中提到的少数几种方法之一)是将typedef作为公共成员,Widget
然后使用Widget::Ptr
:
class Widget {
// ...
public:
typedef boost::shared_ptr<Widget> Ptr;
};
Run Code Online (Sandbox Code Playgroud)
同样,我不喜欢这个,因为(i)它表明指针类型在某种程度上是类的成员,并且(ii)它导致一个不稳定的接口.更糟糕的是:因为我编写的每个类都可能指向使用智能指针,我最终会追逐想象中的客户端尾部.丑陋,丑陋,丑陋.
就目前而言,我已经从这个代码库中删除了typedef(因为它们导致严重的混淆,重复)并在选定的函数中重新引入它们.这里再次出现了使用不一致的问题,但并不是那么严重.
我能想到的唯一其他解决方案 - 我不确定这是否被认为是一种好的做法 - 将是一个实用程序头,其中放置了typedef,可能在他们自己的命名空间内.在这个标题中,我们将包括并完成它.
我错过了一些明显的东西,或者这简直太难了?
PS-道歉的长度; 我找不到一种更简单的方法来充分表达问题.
此外,在声明Widget本身期间输入boost :: shared_ptr似乎没有意义 - 我们似乎将Widget的声明与对客户端如何使用Widget接口的预期相混合.
首先,这完全没有错 - 毕竟,客户端将如何(并且可以)使用接口的方式是接口本身的一部分; 对于C++而言,不是垃圾收集,对象的内存管理是其界面的一个相当重要的部分.
所以有两种情况.在一种情况下,Widget
预期它将通过共享指针使用.这意味着,例如.从窗口小部件获取的子窗口小部件返回为shared_ptr
s,创建的每个窗口小部件都有它shared_ptr
,依此类推.WidgetPtr
在相同的标题中输入undef是完全合法的Widget
.
在第二种情况下,Widget
s期望被管理,例如.通过普通new
和delete
.客户可以shared_ptr
在特殊情况下使用s,但没有说明例如.打印机对话例程不能auto_ptr
代替使用.客户必须准备好,如果wptr
是a shared_ptr
,那条线
shared_ptr<Widget> w2(wptr->firstChild()->parent());
Run Code Online (Sandbox Code Playgroud)
导致灾难.
你的问题似乎表明后者是你的情况.恕我直言,你所做的就是好的.客户可以选择管理Widget
对象的方式,只要它不影响其他客户端.
我不喜欢一个规定使用特定智能指针的库,但如果有必要,我会容忍它.
如果你想强迫用户总是用a shared_ptr
来操作一个小部件,这是不可能的,所以甚至不用费心去尝试.
另一方面,如果你有一个Widget
返回a 的方法boost::shared_ptr<Widget>
,那么提供一个(理智的)typedef可能会简化客户端代码.
因此,我会推广使用内部typedef:
class Widget
{
public:
typedef boost::shared_ptr<Widget> Ptr;
Ptr AccessFirstChild();
}; // class Widget
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它是完全可以#include
的必要的标题.
在我看来,你是在思考这个问题.shared_ptr<Widget>
无论如何,每个想拥有a 的人都必须包含Widget头文件.把typedef
(这是一个好主意imo)放在Widget.h
100%的意义上.