tun*_*unc 1 c++ tr1 shared-ptr c++11
我可以访问null shared_ptr对象的成员函数:
#include <memory>
#include <iostream>
class A
{
public:
int getNum() {return 1234;}
};
int main()
{
std::shared_ptr<A> pA(nullptr);
std::cout << pA->getNum() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
当我期待一个例外时返回1234.同样的结果发生了
std::shared_ptr<A> pA();
Run Code Online (Sandbox Code Playgroud)
要么
std::shared_ptr<A> pA();
pA.reset();
Run Code Online (Sandbox Code Playgroud)
这真的是预期的行为吗?如果是corect shared_ptr defination在成员函数调用的情况下抛出异常是什么?
使用VS2010.
调用operator->()a shared_ptr[util.smartptr.shared.obs]:
5 要求:
get() != 0.
这意味着如果get() == 0在您调用时operator->(),您将获得未定义的行为.未定义的行为意味着任何事情都可能发生:您可能会遇到异常.你可以得到你期望的结果(不管是什么).你可以备份最近的主要城市的所有厕所.没有任何说服力.
无论您使用此代码执行什么操作,实现都是正确的.
完整的答案在这里:
简短的回答是,是的,这是未定义的行为(或者,至少,在规范中没有明确定义),并且实际行为并非不合理,因为它静态地知道类型并且不引用任何数据在其中.但是,依靠这种行为几乎肯定不是一个好主意.
从技术上讲,你在这里所做的事情确实需要未定义的行为.但是,因为你的getNum方法不是virtual并且没有任何用处this,所以这次碰巧不会崩溃.要了解原因,请想象编译器在内部重写了您的程序,如下所示:
class A { };
int A_getNum(A* this) { return 1234; }
int main()
{
A* pA = 0;
std::cout << A_getNum(pA) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
您可以看到,即使没有实际对象,也永远不会取消引用空指针A,因此它不会崩溃.这shared_ptr是无关紧要的 - 如果您使用裸指针,您将获得相同的效果.
如果你想在空指针上使用时强行 shared_ptr崩溃->,嗯,我不相信有任何标准.你的编译器可能有一个你可以打开的调试选项 - 例如,如果我用gcc 4.5编译你的程序-D_GLIBCXX_DEBUG,我得到
$ ./a.out
/usr/include/c++/4.5/bits/shared_ptr_base.h:710:
_Tp* std::__shared_ptr<_Tp, _Lp>::operator->() const
[with _Tp = A, __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2u]:
Assertion '_M_ptr != 0' failed.
Aborted
Run Code Online (Sandbox Code Playgroud)
抱歉,无法帮助您使用MSVC.
| 归档时间: |
|
| 查看次数: |
847 次 |
| 最近记录: |