C++ C++;设置新对象时是否应销毁对象中的旧对象?
考虑以下类声明:C++ C++;设置新对象时是否应销毁对象中的旧对象?,c++,C++,考虑以下类声明: #include "classB.h" class A { private: B *prop; public: A() { /* does stuff to set up B as a pointer to a new B */ setB(const B& bar) { /* store a copy of B */ // how do I manage the old *prop? *prop = new B(
#include "classB.h"
class A {
private:
B *prop;
public:
A() { /* does stuff to set up B as a pointer to a new B */
setB(const B& bar) { /* store a copy of B */
// how do I manage the old *prop?
*prop = new B(bar);
}
};
在
setB()
中,应该如何管理内存分配?我应该删除旧的*prop
?如果是这样,我是否要取消引用,然后删除?首先,您必须在构造函数中将prop
设置为NULL
,否则,如果尝试删除它,您将得到未定义的行为
其次,您不需要取消引用,只需分配指针
第三,应该删除析构函数中的内存,这样就不会出现泄漏
最后,如果实现析构函数,还应该有一个复制构造函数和赋值运算符
class A {
private:
B *prop;
public:
//set prop to NULL so you don't run into undefined behavior
//otherwise, it's a dangling pointer
A() { prop = NULL; }
//when you set a new B, delete the old one
setB(const B& bar) {
delete prop;
prop = new B(bar);
}
//delete prop in destructor
~A() { delete prop; }
//because you now have a destructor
//implement the following to obey the rule of three
A& operator = (const A& other); //assignment operator
A(const A& other); //copy constructor
};
首先,您必须在构造函数中将prop
设置为NULL
,否则,如果您试图删除它,就会得到未定义的行为
其次,您不需要取消引用,只需分配指针
第三,应该删除析构函数中的内存,这样就不会出现泄漏
最后,如果实现析构函数,还应该有一个复制构造函数和赋值运算符
class A {
private:
B *prop;
public:
//set prop to NULL so you don't run into undefined behavior
//otherwise, it's a dangling pointer
A() { prop = NULL; }
//when you set a new B, delete the old one
setB(const B& bar) {
delete prop;
prop = new B(bar);
}
//delete prop in destructor
~A() { delete prop; }
//because you now have a destructor
//implement the following to obey the rule of three
A& operator = (const A& other); //assignment operator
A(const A& other); //copy constructor
};
如果构造函数总是分配一个新的B
,您可以将该空间重新用于其他B
对象的副本
A() { /* does stuff to set up prop as a pointer to a new B */
}
setB(const B& bar) { /* store a copy of B */
*prop = bar;
}
不要忘记删除析构函数中的prop
。如果构造函数总是分配一个新的B
,您可以将该空间重新用于其他B
对象的副本
A() { /* does stuff to set up prop as a pointer to a new B */
}
setB(const B& bar) { /* store a copy of B */
*prop = bar;
}
不要忘记删除析构函数中的prop
。为了在分配抛出的情况下保持操作前的对象状态,您最好执行如下操作:
void setB(const B& bar)
{
// Do this first, since it could throw.
B *newProp = new B(bar);
// Now delete the old one and replace it with the new one.
delete prop;
prop = newProp;
}
请参见此处(特别是关于强异常保证的部分):
为了在分配抛出的情况下保持对象在操作之前的状态,您最好执行如下操作:
void setB(const B& bar)
{
// Do this first, since it could throw.
B *newProp = new B(bar);
// Now delete the old one and replace it with the new one.
delete prop;
prop = newProp;
}
请参见此处(特别是关于强异常保证的部分):
谢谢路钦!我有一个复制构造函数和析构函数,我只是懒得把它们指进去。非常好的解释,谢谢!非常感谢。:)我将在接受答案的计时器过期后将其标记为解决方案。编写a():prop(NULL){}
可能比分配给prop
更为惯用,但这并不重要。这既不是异常安全的,也不是自分配安全的。(如果你称之为setB(prop),会发生什么情况?)斯图尔特·戈洛德茨(Stuart Golodetz)的单独回答解决了这些问题。(不过,您还需要在这个答案中进行所有其他更改;该更改仅涵盖了setB方法。)谢谢Luchian!我有一个复制构造函数和析构函数,我只是懒得把它们指进去。非常好的解释,谢谢!非常感谢。:)我将在接受答案的计时器过期后将其标记为解决方案。编写a():prop(NULL){}
可能比分配给prop
更为惯用,但这并不重要。这既不是异常安全的,也不是自分配安全的。(如果你称之为setB(prop),会发生什么情况?)斯图尔特·戈洛德茨(Stuart Golodetz)的单独回答解决了这些问题。(不过,在这个答案中,您还需要所有其他的更改;这个更改只包括setB方法。)在这种情况下(构造函数总是分配一个新的B),他可能只需要一个对象而不是一个指针,不是吗?这样会更容易,并解决缺少复制构造函数和赋值运算符的潜在问题。当然,除非B可以安全/便宜地进行复制构造,但不进行复制赋值,在这种情况下,这将不起作用……在这种情况下(构造函数总是分配新B的情况下),他可能只需要一个对象而不是指针,否?这将使它更容易,并解决缺少复制构造函数和赋值运算符的潜在问题。当然,除非B可以安全/便宜地进行复制构造,但不进行复制赋值,在这种情况下,这将不起作用…最好的答案是使用唯一的\u ptr,而不是自己尝试。但很明显,对于家庭作业来说,重点可能是教你unique_ptr在做什么,这可能是不合适的。@abarner在重新分配任务时,unique_ptr会自动清理自己吗?谢谢。嗯,unique_ptr上没有赋值运算符。您必须显式地调用reset方法。但是,是的,该方法将自动删除旧值,并且它还处理下面答案中提出的所有其他复杂性。有关详细信息,请参阅。唯一的问题是它需要C++11;如果您必须使用C++03,请转而使用boost::scoped_ptr(灵活性稍差,但只要您不需要额外的灵活性,它也一样好)。最好的答案是使用一个独特的_ptr,而不是自己尝试。但很明显,对于家庭作业来说,重点可能是教你unique_ptr在做什么,这可能是不合适的。@abarner在重新分配任务时,unique_ptr会自动清理自己吗?谢谢。嗯,unique_ptr上没有赋值运算符。您必须显式地调用reset方法。但是,是的,该方法将自动删除旧值,并且它还处理下面答案中提出的所有其他复杂性。有关详细信息,请参阅。唯一的问题是它需要C++11;如果您必须使用C++03,请改用boost::scoped_ptr(灵活性稍差,但只要您不需要额外的灵活性,它就一样好)。