如何避免在分配/返回时破坏对象
How to avoid destroying an object on assignment / returning
这是一个示例类:
struct peel {
int* p;
bool nodelete;
peel() {
nodelete = false;
}
~peel() {
if (!nodelete) delete p;
}
peel& operator=(const peel& other) {
p = other.p;
nodelete = true;
}
};
struct banana {
peel getPeel() {
peel ret;
ret.p = new int();
return ret;
}
};
所以当我打电话
banana peelSource;
auto myPeel = peelSource.getPeel();
我无法使用 myPeel,因为在返回和赋值之间的某个地方,peel 对象的析构函数被调用,当指针被复制时,分配的内存消失了,因此指针无效。
为什么我想像这样创建对象:
- 在我的实际课堂上,香蕉包含许多对果皮的创建至关重要的信息,总的来说,让香蕉构建果皮更容易。
- 我不想分配带有 new 的剥离并返回一个指针,因为对于一个我喜欢剥离一旦超出范围就会自动销毁的便利性,而且 peel 有一个括号运算符,这更好,而不必首先取消引用括号中的剥离。
赋值运算符是我试图避免删除内容,但它从未调用过,不确定我是否做对了。
无论如何,我如何使自动 myPeel = peelSource.getPeel((; 工作而不让它删除数据?
你写道:
我不想分配带有 new 的剥离并返回一个指针,因为对于一个我喜欢剥离一旦超出范围就会自动销毁的便利性,而且 peel 有一个括号运算符,这更好,而不必首先取消引用括号中的剥离。
您可以考虑以下几点。首先使用所需的接口(例如,括号运算符(编写peel
。将所有内容保存为常规值成员,不带指针、指示不删除的布尔标志等。
struct peel
{
/* Hold here everything as regular value members, without
pointers or boolean flags indicating whether to delete, and
so forth.*/
// Here's your brackets operator.
... operator[](...);
};
现在只需使用这个
struct banana
{
peel getPeel() {
peel ret;
...
return ret;
}
};
配置文件以查看使用它是否有任何问题。由于NRVO的原因,很有可能不会有。
如果由于某种原因,您发现无法按值有效地操作peel
对象,请考虑按如下方式重构。首先,将所有重部件移动到peel_imp
(再次避免指针和布尔标志(。
// "Heavy" peel stuff.
struct peel_imp
{
/* Hold here everything as regular value members, without
pointers or boolean flags indicating whether to delete, and
so forth.*/
};
然后,正如@EdHeal注释中所建议的那样,使用智能指针来保存实现。
struct peel
{
... operator[](...);
std::shared_ptr<peel_imp> m_imp;
};
再次使peel
对象对值操作有效。
为什么要在分配时销毁对象并返回。它将是无效的指针并且无用。更好的选择是使用移动构造函数/移动赋值运算符。
相关文章:
- 如何通过另一个对象中的命令正确地从一个对象返回数据
- 如何访问从 COM 对象返回的 VARIANT 数据类型中的安全数组C++?
- 从我的对象返回静态数组
- 将unique_ptr作为<Object>unique_ptr<常量对象返回>
- 从右值对象返回成员
- 视觉对象 返回 C++ 中的双精度值
- 为什么类型为 sf::Text 的对象返回不同的 getPosition().y 和 getLocalBounds().
- std::min_element 从类对象返回意外结果
- C++无效的对象返回语义
- const引用是否延长临时对象返回的临时对象的寿命
- 将 NULL 作为对象返回时未收到任何警告
- 如何在 C# 中从 com 对象返回数组(double[])
- 从重载运算符返回引用,并使用临时对象返回表达式
- Cin 对象返回值 c++
- 将变量作为类对象返回
- 使用可更改对象返回只读的最佳方法是什么
- 如何在Cython中从另一个包装对象返回包装的c++对象
- 当对象返回时,c++动态数组被清除
- 从带有动态字段的函数、对象返回
- 从堆栈上的匿名对象返回对*this的引用