为什么指针即使在分配给它的unique_ptr超出范围后仍然存在
Why does the pointer exist even after the unique_ptr to which the pointer is assigned goes out of scope?
我最近开始学习C++中的智能指针和移动语义。但我不明白为什么这个代码有效。我有这样的代码:
#include <iostream>
#include <memory>
using namespace std;
class Test
{
public:
Test()
{
cout << "Object created" << endl;
}
void testMethod()
{
cout << "Object existing" << endl;
}
~Test()
{
cout << "Object destroyed" << endl;
}
};
int main(int argc, char *argv[])
{
Test* testPtr = new Test{};
{
unique_ptr<Test> testSmartPtr(testPtr);
}
testPtr->testMethod();
return 0;
}
我的输出是:
Object created
Object destroyed
Object existing
为什么行testPtr->testMethod()
工作?如果指针是左值,unique_ptr不会删除销毁时分配给它的指针吗?
编辑:我从评论中了解到,这个方法不检查指针是否存在。如果是,有没有办法检查指针是否有效?
编辑:我学会了不应该用无效指针做任何事情。感谢您的回答和评论。
编辑:即使这个代码工作:
#include <iostream>
#include <memory>
using namespace std;
class Test
{
public:
Test(int num) :
number{ num }
{
cout << "Object created" << endl;
}
void testMethod(int valueToAdd)
{
number += valueToAdd;
cout << "Object current value: " << number << endl;
}
~Test()
{
cout << "Object destroyed" << endl;
}
private:
int number;
};
int main(int argc, char *argv[])
{
Test* testPtr = new Test(42);
{
unique_ptr<Test> testSmartPtr(testPtr);
}
testPtr->testMethod(3);
return 0;
}
我想这是因为编译器优化了它。无论如何,我真的不应该对无效指针做任何事情。
您不需要std::unique_ptr
来编写具有相同问题的代码
int main(int argc, char *argv[])
{
Test* testPtr = new Test{};
delete testPtr;
testPtr->testMethod(); // UNDEFINED !!!
return 0;
}
这里的输出与您的相同https://godbolt.org/z/8bocKGj1M,但它可能完全是另一回事。该代码具有未定义的行为。不能取消引用无效的指针。
如果您在testMethod()
中实际使用了对象的成员,则更有可能出现错误输出或崩溃,但也不能保证。看起来很好是未定义行为的最糟糕体现。
您的代码很好地说明了为什么应该完全禁止原始new
。至少您应该只将new
作为智能指针构造函数的参数来调用,或者更好的是,使用std::make_unique
。它基本上只是通过new
对构造函数调用的包装,它的主要目的是让您编写不含new
:的代码
int main(int argc, char *argv[])
{
auto testPtr = std::make_unique<Test>();
testPtr->testMethod();
return 0;
}
即使这样,你也可以访问原始指针并做错误的事情。聪明的指针有助于提高所有权,但它们并不是傻瓜式的。
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- 尝试通过多个向量访问变量时,向量下标超出范围
- 错误:未在此范围内声明'reverse'
- 正在将指针转换为范围
- 使用std::transform将一个范围的元素添加到另一个范围中
- 在基于范围的for循环中使用结构化绑定声明
- 如何计算数据类型的范围,例如int
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 在C++中查找范围的长度
- 如何设置一个范围来提取我想要获得的信息
- 并行用于C++17中数组索引范围内的循环
- 为左值和右值的包装器实现C++范围
- CLANG 编译器 说:变量"PTR"可能未初始化
- 求出有多少个数字是完美平方,而sqrt()是L,R范围内的素数
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 超出范围时使用对象
- 唯一/共享 ptr 用于在数组超出范围后自动删除阵列
- 如何检测ptr在引用超出范围后是否仍在引用有效引用
- 如何设置 Excel 范围 Ptr 的值 = C++值?目前我得到 HRESULT 0x80004005
- 当可以在类对象超出范围之前删除此数据时,类允许访问其数据(通过 ptr/it)是否设计不好