也许我过于复杂了,但话又说回来,我有点像干净的界面。假设我想要一个fstream的auto_ptr专门化 - 我想要一个普通情况的默认fstream,但允许替换指针?
template <>
class auto_ptr<fstream> {
static fstream myfStream;
fstream* ptr;
public:
auto_ptr() {
// set ptr to &myfStream;
}
reset(fstream* newPtr) {
// free old ptr if not the static one.
ptr = newPtr
};
}
你会考虑不同或更优雅的东西吗?你会如何保持上述内容在这个特定的编译单元之外传播?
[实际模板是boost :: scoped_ptr。]
编辑:
这是一个人为的例子。忽略fstream - 它是关于为auto_ptr提供对象的默认实例。我可能不想提供专门的实例,但希望保留此静态默认对象的auto_ptr语义。
class UserClass {
public:
auto_ptr<fstream> ptr;
UserClass() { }
}
我可能不会在施工时提供动态对象 - 我仍然希望它有一个有意义的默认值。由于我不是在考虑所有权转移语义,所以我的指针类指向静态分配的对象真的不重要,不是吗?
答案 0 :(得分:2)
这不会结束。最大的问题是std :: auto_ptr删除了析构函数中的底层对象。这意味着您的默认参数不能是静态的。你可以做的唯一选择是在那里做很多黑客,恕我直言,你要支付的价格,同时保持所有糟糕的代码不值得你的小优势。
答案 1 :(得分:1)
这对我来说看起来很合理,如果它的使用在代码库中很普遍而且没有记录,可能会让人感到困惑。
我注意到你很乖,但我还是要强调它:确保你没有双重释放你的静态物体!
答案 2 :(得分:1)
你可能会得到一些编译和工作的东西,但如果我是你,我就不会这样做。
Boost定义了构建auto_ptr
的某些功能。如果以某种方式重新定义,则违反了他们的规范。
为您的新功能创建一个名称,使其成为工厂功能,而不必担心专门化其他人的模板。
EDIT:派生自auto_ptr
是另一种选择,如果你真的开始改变初始化语义:
tempate < class T, T *d >
struct defaulted_auto_ptr
: public auto_ptr< T > {
defaulted_auto_ptr( T *p = d ) throw() : auto_ptr<T>( p ) {} // set default
defaulted_auto_ptr( auto_ptr<T> &r ) throw()
: auto_ptr<T>( r ) {} // allow conversion
template< class O > defaulted_auto_ptr( auto_ptr<O> &r ) throw()
: auto_ptr<T>( r ) {}
};
fstream default_file;
typedef defaulted_auto_ptr< fstream, &default_file > file_ptr;
auto_ptr< fstream > baseptr = file_ptr(); // can assign to auto_ptr, but unsafe
我对此的成本 - 收益权衡有点怀疑,但它比完全重新实现auto_ptr
要好。
如果默认对象被销毁,你仍然需要弄清楚该做什么。上面的default_file
可能是delete
d,可能是多次。