如果我在具有自动存储持续时间(即存储在堆栈中)的对象上应用智能指针(scoped_ptr
,unique_ptr
或shared_ptr
),是否会出现问题?我假设不是在两种情况下(有和没有智能指针),如果没有更多的指针指向它们,它们将被删除。指针本身总是具有自动存储持续时间,即如果它们超出范围则将被删除。
答案 0 :(得分:4)
是,有一个问题(一个大问题):你正在使用智能指针做一些事情(我不知道是什么)他们不是设计的。它们旨在管理动态分配对象的生命周期。它们解决了从C
继承的问题,它们为需要动态分配/释放的对象提供所有权(它们不限于内存(指针);您实际上可以使用智能指针来管理任何类型的资源,需要获取/释放,例如系统资源,文件描述符等)。
好的,但除了哲学问题,是否存在实际问题?
是!! 强>。智能指针将在拥有的对象上调用delete
/ delete[]
,当未分别从new
/ new[]
获取指针时,这是未定义的行为。
是的,你可以使用一个什么都不做的自定义删除工具,但那么使用智能指针又有什么意义呢?
答案 1 :(得分:2)
以下是demo:
class Foo{
public:
Foo(){cout << "Foo created!\n";}
~Foo(){cout << "Foo destroyed!\n";}
};
void go(){
Foo foo;
cout << "Position A\n";
{
Foo foo1;
}
cout << "Position B\n";
{
Foo *foo2;
}
cout << "Position C\n";
{
Foo *foo3 = new Foo;
}
cout << "Position D\n";
{
std::shared_ptr<Foo> foo3(new Foo);
}
cout << "Position E\n";
{
std::shared_ptr<Foo> foo3(&foo);
}
cout << "Position F\n";
}
输出为:
Foo created!
Position A
Foo created!
Foo destroyed!
Position B
Position C
Foo created!
Position D
Foo created!
Foo destroyed!
Position E
Foo destroyed!
以
结尾运行时错误: 错误:free():无效指针:0x00007ffda60f0e67
注意位置DE和位置EF之间的区别(删除不是来自新的指针,因此导致未定义的行为)。
答案 2 :(得分:1)
是的,这是一个问题,因为智能指针将(暂时忽略自定义删除器)对未通过delete
(即UB)创建的对象调用new
并且将调用析构函数两次(这也会导致未定义的行为)。
它会顺便说一句。如果您尝试通过两个独立的智能指针管理对象,也会导致错误。
因此,在涉及终身管理的地方,&#34;越多越好&#34; 绝对不是真的。