如何安全地将 new 创建的对象传递给构造函数
How to safely pass objects created by new into constructor
我有几个 class 是这样的:
struct equation {};
struct number: equation {
number(int n): value(n) {}
private:
int value;
};
struct operation: equation {
operation(const equation* left, const equation* right)
: left(left), right(right) {}
private:
std::unique_ptr<equation> left, right;
};
它们的设计方式是 operation
拥有传递给构造函数的指针的所有权。
我的问题是如何修改此 class 以便能够以下一种方式安全地使用它:
operation op(new number(123), new number(456));
在我看来,如果创建了第一个对象而没有创建第二个对象(比如 number
构造函数抛出异常),那么这是内存泄漏 - 没有人会删除指向第一个对象的指针数.
遇到这种情况我该怎么办?我不想按顺序分配对象并在出现问题时删除它们——这太冗长了。
I do not want to allocate objects sequentially and delete them if something has failed - it's too verbose.
是的。你只需要更彻底地应用智能指针成语即可;更准确地说,将参数类型更改为 std::unique_ptr
, and use std::make_unique
(since C++14)(而不是显式使用 new
)以避免此问题。例如
struct operation: equation {
operation(std::unique_ptr<equation> left, std::unique_ptr<equation> right)
: left(std::move(left)), right(std::move(right)) {}
private:
std::unique_ptr<equation> left, right;
};
然后
operation op(std::make_unique<number>(123), std::make_unique<number>(456));
注意std::make_unique
的使用在这里很重要,在std::make_unique
内部创建的原始指针保证由返回的std::unique_ptr
管理;即使是第二个 std::make_unique
也失败了
std::unique_ptr
由第一个 std::make_unique
创建的将确保它拥有的指针被销毁。对于首先调用第二个 std::make_unique
的情况也是如此。
在 C++14 之前,您可以制作自己的 std::make_unique
版本;一个基本的很容易写。 Here 是一个可能的实现。
// note: this implementation does not disable this overload for array types
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
我有几个 class 是这样的:
struct equation {};
struct number: equation {
number(int n): value(n) {}
private:
int value;
};
struct operation: equation {
operation(const equation* left, const equation* right)
: left(left), right(right) {}
private:
std::unique_ptr<equation> left, right;
};
它们的设计方式是 operation
拥有传递给构造函数的指针的所有权。
我的问题是如何修改此 class 以便能够以下一种方式安全地使用它:
operation op(new number(123), new number(456));
在我看来,如果创建了第一个对象而没有创建第二个对象(比如 number
构造函数抛出异常),那么这是内存泄漏 - 没有人会删除指向第一个对象的指针数.
遇到这种情况我该怎么办?我不想按顺序分配对象并在出现问题时删除它们——这太冗长了。
I do not want to allocate objects sequentially and delete them if something has failed - it's too verbose.
是的。你只需要更彻底地应用智能指针成语即可;更准确地说,将参数类型更改为 std::unique_ptr
, and use std::make_unique
(since C++14)(而不是显式使用 new
)以避免此问题。例如
struct operation: equation {
operation(std::unique_ptr<equation> left, std::unique_ptr<equation> right)
: left(std::move(left)), right(std::move(right)) {}
private:
std::unique_ptr<equation> left, right;
};
然后
operation op(std::make_unique<number>(123), std::make_unique<number>(456));
注意std::make_unique
的使用在这里很重要,在std::make_unique
内部创建的原始指针保证由返回的std::unique_ptr
管理;即使是第二个 std::make_unique
也失败了
std::unique_ptr
由第一个 std::make_unique
创建的将确保它拥有的指针被销毁。对于首先调用第二个 std::make_unique
的情况也是如此。
在 C++14 之前,您可以制作自己的 std::make_unique
版本;一个基本的很容易写。 Here 是一个可能的实现。
// note: this implementation does not disable this overload for array types
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}