C++强制使用unique_ptr进行动态分配
C++ force dynamic allocation with unique_ptr?
我发现unique_ptr可以指向已经存在的对象。例如,我可以这样做:
class Foo {
public:
Foo(int nb) : nb_(nb) {}
private:
int nb_;
};
int main() {
Foo f1(2);
Foo* ptr1(&f1);
unique_ptr<Foo> s_ptr1(&f1);
return 0;
}
我的问题是:
如果我创建一个类unique_ptr
例:
class Bar {
public:
Bar(/* arguments */) { /* data members allocation */ }
Bar(Bar const& b) = delete;
/* Other member functions */
private:
/* data members */
};
class Bar_Ptr {
public:
Bar_Ptr(Bar* ptr) {
if (ptr != nullptr) { ptr_ = unique_ptr<Bar> (ptr); }
} /* The user can still pass the address of an already existing Bar ... */
/* Other member functions */
private:
unique_ptr<Bar> ptr_;
};
你不能阻止程序员做愚蠢的事情。std::unique_ptr
和std::shared_ptr
都包含使用现有 ptr 创建实例的选项。我什至见过传递自定义删除程序以防止删除的情况。(对于这些情况,共享 ptr 更优雅)
因此,如果您有指针,则必须知道它的所有权。这就是为什么我更喜欢使用std::unique_ptr
、std::shared_ptr
和std::weak_ptr
作为"拥有"指针,而原始指针表示非拥有指针。如果将其传播到创建对象的位置,则大多数静态分析器可以告诉您犯了错误。
因此,我会将类Bar_ptr重写为如下所示的内容:
class Bar_ptr {
public:
explicit Bar_ptr(std::unique_ptr<Bar> &&bar)
: ptr(std::move(bar)) {}
// ...
}
这样,类的 API 将强制执行所有权转移,并且由调用方提供有效的unique_ptr。换句话说,您不必担心传递未分配的指针。
没有人阻止呼叫者写:
Bar bar{};
Bar_ptr barPtr{std::unique_ptr<Bar>{&bar}};
虽然如果你有一个像样的静态分析器,甚至只是一个代码审查,我希望这段代码被拒绝。
不,你不能。你不能阻止人们做愚蠢的事情。声明一个基于模板化参数返回新对象的模板化函数。
我以前见过类似的东西。诀窍是你创建一个函数(我们称之为make_unique
),它接受对象(不是指针,对象,所以也许使用隐式构造函数,它可以"接受"类构造函数参数),这个函数将创建并返回unique_ptr
。像这样:
template <class T> std::unique_ptr<T> make_unique(T b);
顺便说一句,你可以推荐人们使用这个功能,但没有人会强迫他们做你推荐的事情......
你不能阻止人们做错事。但你可以鼓励他们做正确的事。或者至少,如果他们做错了事,那就让它更明显。
例如,对于 Bar
,不要让构造函数采用裸指针。按值或按&&
取 unique_ptr
秒。这样,您可以强制调用方创建这些unique_ptr
。您只需将它们移动到成员变量中即可。
做了错误的事情,错误就出在调用方的代码中,而不是你的代码中。
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 在c++中使用动态分配的问题
- 使用递归模板动态分配的多维数组
- 对具有动态分配的内存和析构函数的类对象的引用
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 访问动态分配列表中的元素
- 为什么 std::equal_to会导致动态分配?
- 调用析构函数以释放动态分配的内存
- 动态分配Q_Property变量
- 在 C++ 中搜索动态分配的数组中的出现次数
- 动态分配的聊天数组打印缺失的数据和空
- 在对象指针上调用 Delete 是否会递归删除其动态分配的成员
- 使用动态分配将 char* 复制到另一个字符**
- 使用指针在存在特征库的情况下动态分配 c++ 中的矩阵
- 二维阵列的动态分配
- 0xC0000005:访问冲突写入位置0xCDCDCDCD动态分配错误
- 在运行时为动态分配的内存输入值
- 释放动态分配的内存时是否需要执行此额外步骤
- 动态分配字符数组的内存