Rom*_*huk 1 c++ pointers memory-management smart-pointers unique-ptr
我最近开始学习 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;
}
Run Code Online (Sandbox Code Playgroud)
我的输出是:
Object created
Object destroyed
Object existing
Run Code Online (Sandbox Code Playgroud)
为什么行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;
}
Run Code Online (Sandbox Code Playgroud)
我认为这是因为编译器优化了它。不管怎样,我真的不应该用无效的指针做任何事情。
您不需要std::unique_ptr编写具有相同问题的代码
int main(int argc, char *argv[])
{
Test* testPtr = new Test{};
delete testPtr;
testPtr->testMethod(); // UNDEFINED !!!
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出与您的输出相同https://godbolt.org/z/8bocKGj1M,但它可能完全是其他东西。该代码具有未定义的行为。您不得取消引用无效的指针。
如果您实际上在中使用了该对象的成员testMethod(),则崩溃的可能性更大,但也不能保证。看起来不错是未定义行为的最糟糕的化身。
您的代码很好地说明了为什么您应该new完全禁止 raw。至少您应该new仅作为参数调用智能指针构造函数,或者更好的是,使用std::make_unique. 它基本上只是构造函数调用的包装器new,其主要目的是让您编写不包含以下内容的代码new:
int main(int argc, char *argv[])
{
auto testPtr = std::make_unique<Test>();
testPtr->testMethod();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
即使这样,您也可以访问原始指针并执行错误的操作。智能指针有助于所有权,但它们并不是万无一失的。
| 归档时间: |
|
| 查看次数: |
136 次 |
| 最近记录: |