BWG*_*BWG 3 memory pointers unique-ptr c++11
unique_ptr本质上不是与对象的直接实例相同吗?我的意思是,动态继承和性能存在一些差异,但仅此而已unique_ptr吗?
考虑此代码以了解我的意思。这不是:
#include <iostream>
#include <memory>
using namespace std;
void print(int a) {
cout << a << "\n";
}
int main()
{
unique_ptr<int> a(new int);
print(*a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
几乎完全一样:
#include <iostream>
#include <memory>
using namespace std;
void print(int a) {
cout << a << "\n";
}
int main()
{
int a;
print(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
还是我误解了unique_ptr应该用于什么?
的目的std::unique_ptr是为动态分配的内存提供自动和异常安全的释放(与必须显式deleted 才能释放的原始指针不同,并且在交错异常的情况下很容易无意中不被释放)。
但是,您的问题更多地是关于指针的一般价值而不是std::unique_ptr具体的。对于像 这样的简单内置类型int,通常没有理由使用指针而不是简单地按值传递或存储对象。但是,在三种情况下,指针是必要的或有用的:
无效或未设置
指针支持一个nullptr附加值,指示尚未设置指针。例如,如果您想支持给定类型的所有值(例如整个整数范围),但也表示用户从不在界面中输入值的概念,那就是使用 a 的情况std::unique_ptr<int>,因为您可以获取指针是否为空作为指示它是否已设置的一种方式(不必丢弃有效的整数值只是为了将该特定值用作无效的“哨兵”值表示它未设置) .
允许修改
这也可以通过引用而不是指针来完成,但指针是一种方法。如果您使用常规值,那么您正在处理原始值的副本,并且任何修改仅影响该副本。如果您使用指针或引用,您可以让原始实例的所有者看到您的修改。使用唯一指针,您还可以确保没有其他人拥有副本,因此无需锁定即可安全修改。
多态类型
这同样可以使用引用来完成,而不仅仅是使用指针,但在某些情况下,由于所有权或分配的语义,您可能希望使用指针来执行此操作......当涉及到用户定义的类型时,它是可以创建分层的“继承”关系。如果您希望您的代码对给定类型的所有变体进行操作,那么您需要使用指向基类型的指针或引用。std::unique_ptr<>用于此类事情的一个常见原因是,如果对象是通过工厂构造的,您定义的类在该工厂中维护所构造对象的所有权。例如:
class Airline {
public:
Airline(const AirplaneFactory& factory);
// ...
private:
// ...
void AddAirplaneToInventory();
// Can create many different type of airplanes, such as
// a Boeing747 or an Airbus320
const AirplaneFactory& airplane_factory_;
std::vector<std::unique_ptr<Airplane>> airplanes_;
};
// ...
void Airline::AddAirplaneToInventory() {
airplanes_.push_back(airplane_factory_.Create());
}
Run Code Online (Sandbox Code Playgroud)
除了 Chris Pitman 提到的情况之外,您还需要使用的另一种情况std::unique_ptr是,如果您实例化足够大的对象,那么在堆中而不是在堆栈中进行操作是有意义的。堆栈大小不是无限的,迟早您可能会遇到堆栈溢出。这就是std::unique_ptr有用的地方。