auto_ptr <t> </t>的模板特化

时间:2010-04-07 13:26:16

标签: c++ templates

也许我过于复杂了,但话又说回来,我有点像干净的界面。假设我想要一个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() {  }
} 

我可能不会在施工时提供动态对象 - 我仍然希望它有一个有意义的默认值。由于我不是在考虑所有权转移语义,所以我的指针类指向静态分配的对象真的不重要,不是吗?

3 个答案:

答案 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,可能是多次。