是否有任何理由在std :: auto_ptr的构造函数中使用`explicit`关键字?

时间:2011-11-17 12:50:33

标签: c++

这是用于在VS2008编译器中从标准指针构造std :: auto_ptr对象的ctor。

template<class _Ty>
class auto_ptr
{
   public:
   explicit auto_ptr(_Ty *_Ptr = 0) _THROW0() : _Myptr(_Ptr) {}

   private:
   _Ty *_Myptr;
};

上面使用explicit关键字是否有任何特殊原因?

换句话说,为什么我不能用

初始化auto_ptr

std::auto_ptr<Class A> ptr = new Class A;

4 个答案:

答案 0 :(得分:7)

因为你可能无意中做了类似的事情:

void foo(std::auto_ptr<int> p)
{
}

void boo()
{
    int* p = new int();
    foo(p);
    delete p; // oops a bug, p was implicitly converted into auto_ptr and deleted in foo.... confusing
}

与您实际明确了解正在发生的事情的地方相反:

void boo()
{
    int* p = new int();
    foo(std::auto_ptr<int>(p)); // aha, p will be destroyed once foo is done.
}

答案 1 :(得分:2)

构建std::auto_ptr是所有权转移。对所有参与者而言,最好保持所有权转让。例如:

void frobnicate(const std::auto_ptr<Class> & ptr);

Class *instance = new Class();
frobnicate(instance);
delete instance;

如果构造函数是隐式的,那么这段代码就会被编译,如果没有检查frobnicate的定义,几乎不可能注意到它是错误的。此外,虽然现在使用=进行初始化比较困难,但您仍然可以使用其他初始化语法:

std::auto_ptr<Class> instance(new Class);
frobnicate(instance);

答案 2 :(得分:1)

首先,解决这个问题,你可以像这样初始化它:

std::auto_ptr<Class A> ptr(new A);

其次,隐式转换可能会带来更多的弊大于利,因此,如果隐含性可能很有价值,那么构造函数可以使用单个参数显式调用,然后进行思考,这是一个很好的反射。

答案 3 :(得分:0)

使用时出了什么问题:

std::auto_ptr<T> ptr(new T());

如果你允许隐式转换,那么你可以遇到各种各样的问题,在最不期望的地方插入隐式转换。