我正在阅读 Effective C++ 第三版。在第 70 页,作者说:
Like virtually all smart pointer classes,
tr1::shared_ptr
andauto_ptr
also overload the pointer dereferencing operators (operator->
andoperator*
), and this allows implicit conversion to the underlying raw pointers (...)
然后他展示了一个带有 shared_ptr
的示例(当时是 tr1
的一部分),该示例具有基于名为 Investment
的类的隐式转换:
shared_ptr<Investment> pi1();
bool taxable1 = !(pi1->isTaxFree());
^implicit conversion
shared_ptr<Investment> pi2();
bool taxable2 = !((*pi2).isTaxFree());
^implicit conversion
好吧,从那以后我用 unique_ptr
写了一些测试用例,它们都有效。
我还发现了 unique_ptr
supporting arrays和 shared_ptr
also going to (看注释)。但是,在我的测试中,隐式转换似乎不适用于数组周围的智能指针。
示例:我希望这是有效的...
unique_ptr<int[]> test(new int[1]);
(*test)[0] = 5;
但根据我的编译器(Visual C++ 2015 Update 3),它不是。
然后,通过一些研究,我发现了一些证据表明根本不支持隐式转换......例如这个:https://herbsutter.com/2012/06/21/reader-qa-why-dont-modern-smart-pointers-implicitly-convert-to .
在这一点上我有疑问。 是否支持(标准),还是不支持?
注意:这本书在这个主题上可能有点过时,因为作者还在第 65 页上说“没有像 auto_ptr
或 tr1::shared_ptr
这样的动态分配的东西数组,甚至不在 TR1 中。
最佳答案
嗯,事情是这样的。没有到底层指针的隐式转换,您必须调用特定的 get
成员函数(这是标准库中的一个主题,想想 std::string::c_str
)。
但这是一件好事!隐式转换指针会破坏 unique_ptr
的保证.请考虑以下事项:
std::unique_ptr<int> p1(new int);
std::unique_ptr<int> p2(p1);
在上面的代码中,编译器可以尝试通过p1
指向 p2
! (它不会,因为这个调用无论如何都会模棱两可,但假设它不是)。他们都会调用delete
就可以了!
但我们仍然想像使用原始指针一样使用智能指针。因此所有运算符都重载了。
现在让我们考虑一下您的代码:
(*test)[0] = 5;
它调用unique_ptr::operator*
产生 int&
1。然后你尝试在它上面使用下标运算符。那是你的错误。
如果你有 std::unique_ptr<int[]>
不仅仅是使用 operator[]
句柄提供的重载:
test[0] = 5;
1 正如 David Scarlett 指出的那样,它甚至不应该编译。数组版本不应包含此运算符。
关于c++ - 是否支持从 unique_ptr 到原始指针的隐式转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40625359/