这是用于在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;
?
答案 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());
如果你允许隐式转换,那么你可以遇到各种各样的问题,在最不期望的地方插入隐式转换。