您显示的operator=
内容实际上不会启用您想要的语法。shared_ptr<int> p = new int;
将使用来自 T* 的 shared_ptr 的构造函数和 shared_ptr 的复制构造函数。shared_ptr 两者都有,但你的语法不起作用,因为 T* 的构造函数是explicit
.
这样做的原因是,如果该构造 ,std::shared_ptr<int> test = new int;
可以隐式完成,则意味着 shared_ptr 可以在没有任何人明确要求的情况下获得指针的所有权。Nawaz 给出了一个非常容易出错的原因。您必须非常小心,您正在使用的指针不会在您不知情的情况下突然被某处的 shared_ptr 采用,然后从您的下方销毁。
这是一个显示这种危险的隐式构造的示例:
#include <iostream>
template<typename T>
struct owning_pointer {
T *t;
owning_pointer(T *t) : t{t} {}
~owning_pointer() {
std::cout << t << " deleted\n";
delete t;
}
};
void foo(owning_pointer<int> thief) {}
int main() {
int *i = new int;
std::cout << i << " allocated\n";
foo(i);
}
输出将类似于:
0x10d400880 allocated
0x10d400880 deleted
explicit
并查看添加到 owning_ptr 的构造函数时出现的错误。我得到:
main.cpp:18:5: error: no matching function for call to 'foo'
foo(i);
^~~
main.cpp:13:6: note: candidate function not viable: no known conversion from 'int *' to 'owning_pointer<int>' for 1st argument;
void foo(owning_pointer<int> thief) {}
^
此外,没有必要允许从 T* 进行隐式构造,因为已经有一些非常简单的分配方法,而不会产生同样的错误可能性:
std::shared_ptr<int> test(new int); // one extra character isn't a hardship. I typically prefer () construction anyway.
std::shared_ptr<int> test{new int}; // although I might start preferring {} construction in C++11
auto test = std::make_shared<int>(); // this is slightly different in that the allocated int is zero-initialized
如果您正在初始化一个成员 shared_ptr 那么您可以在初始化列表中初始化它,而不是使用赋值或reset()
在构造函数的主体中:
struct foo {
std::shared_ptr<int> m_meh;
foo()
: m_meh(new int)
{
// no need for m_meh.reset(new int) here
}
};
可以实现的是operator=
:
shared_ptr<int> s;
s = new int;
这似乎不像从 T* 隐式构造 shared_ptr 那样容易出错,但我也看不出它真的有任何价值。