设定值(val); } int GetBaseValue()常量 { 返回(base->GetValue()); } 作废打印() { cout,c++,copy-constructor,C++,Copy Constructor" /> 设定值(val); } int GetBaseValue()常量 { 返回(base->GetValue()); } 作废打印() { cout,c++,copy-constructor,C++,Copy Constructor" />

C++;:实现复制构造函数和复制赋值运算符 在阅读C++中的复制构造函数和复制赋值操作符之后,我尝试创建一个简单的例子。虽然下面的代码片段显然有效,但我不确定是否以正确的方式实现了复制构造函数和复制赋值运算符。请您指出是否有任何错误/改进或更好的示例来理解相关概念 class Foobase { int bInt; public: Foobase() {} Foobase(int b) { bInt = b;} int GetValue() { return bInt;} int SetValue(const int& val) { bInt = val; } }; class Foobar { int var; Foobase *base; public: Foobar(){} Foobar(int v) { var = v; base = new Foobase(v * -1); } //Copy constructor Foobar(const Foobar& foo) { var = foo.var; base = new Foobase(foo.GetBaseValue()); } //Copy assignemnt operator Foobar& operator= (const Foobar& other) { if (this != &other) // prevent self-assignment { var = other.var; base = new Foobase(other.GetBaseValue()); } return *this; } ~Foobar() { delete base; } void SetValue(int val) { var = val; } void SetBaseValue(const int& val) { base->SetValue(val); } int GetBaseValue() const { return(base->GetValue()); } void Print() { cout<<"Foobar Value: "<<var<<endl; cout<<"Foobase Value: "<<base->GetValue()<<endl; } }; int main() { Foobar f(10); Foobar g(f); //calls copy constructor Foobar h = f; //calls copy constructor Foobar i; i = f; f.SetBaseValue(12); f.SetValue(2); Foobar j = f = z; //copy constructor for j but assignment operator for f z.SetBaseValue(777); z.SetValue(77); return 1; } class-Foobase { int bInt; 公众: Foobase(){} Foobase(intb){bInt=b;} int GetValue(){return bInt;} int SetValue(const int&val){bInt=val;} }; 福巴级 { int-var; Foobase*base; 公众: Foobar(){} Foobar(INTV) { var=v; 基准=新的食品基准(v*-1); } //复制构造函数 Foobar(const Foobar&foo) { var=foo.var; base=newfoobase(foo.GetBaseValue()); } //复制赋值运算符 Foobar&运算符=(const Foobar&其他) { if(this!=&other)//防止自分配 { var=其他变量; base=newfoobase(other.GetBaseValue()); } 归还*这个; } ~Foobar() { 删除基数; } 无效设置值(int val) { var=val; } void SetBaseValue(常量int&val) { 基础->设定值(val); } int GetBaseValue()常量 { 返回(base->GetValue()); } 作废打印() { cout

C++;:实现复制构造函数和复制赋值运算符 在阅读C++中的复制构造函数和复制赋值操作符之后,我尝试创建一个简单的例子。虽然下面的代码片段显然有效,但我不确定是否以正确的方式实现了复制构造函数和复制赋值运算符。请您指出是否有任何错误/改进或更好的示例来理解相关概念 class Foobase { int bInt; public: Foobase() {} Foobase(int b) { bInt = b;} int GetValue() { return bInt;} int SetValue(const int& val) { bInt = val; } }; class Foobar { int var; Foobase *base; public: Foobar(){} Foobar(int v) { var = v; base = new Foobase(v * -1); } //Copy constructor Foobar(const Foobar& foo) { var = foo.var; base = new Foobase(foo.GetBaseValue()); } //Copy assignemnt operator Foobar& operator= (const Foobar& other) { if (this != &other) // prevent self-assignment { var = other.var; base = new Foobase(other.GetBaseValue()); } return *this; } ~Foobar() { delete base; } void SetValue(int val) { var = val; } void SetBaseValue(const int& val) { base->SetValue(val); } int GetBaseValue() const { return(base->GetValue()); } void Print() { cout<<"Foobar Value: "<<var<<endl; cout<<"Foobase Value: "<<base->GetValue()<<endl; } }; int main() { Foobar f(10); Foobar g(f); //calls copy constructor Foobar h = f; //calls copy constructor Foobar i; i = f; f.SetBaseValue(12); f.SetValue(2); Foobar j = f = z; //copy constructor for j but assignment operator for f z.SetBaseValue(777); z.SetValue(77); return 1; } class-Foobase { int bInt; 公众: Foobase(){} Foobase(intb){bInt=b;} int GetValue(){return bInt;} int SetValue(const int&val){bInt=val;} }; 福巴级 { int-var; Foobase*base; 公众: Foobar(){} Foobar(INTV) { var=v; 基准=新的食品基准(v*-1); } //复制构造函数 Foobar(const Foobar&foo) { var=foo.var; base=newfoobase(foo.GetBaseValue()); } //复制赋值运算符 Foobar&运算符=(const Foobar&其他) { if(this!=&other)//防止自分配 { var=其他变量; base=newfoobase(other.GetBaseValue()); } 归还*这个; } ~Foobar() { 删除基数; } 无效设置值(int val) { var=val; } void SetBaseValue(常量int&val) { 基础->设定值(val); } int GetBaseValue()常量 { 返回(base->GetValue()); } 作废打印() { cout,c++,copy-constructor,C++,Copy Constructor,您的复制分配运算符的实现不正确。分配给它的对象泄漏了它的base指向的对象 您的默认构造函数也不正确:它使base和var都未初始化,因此无法知道两者是否有效,在析构函数中,当您调用delete base;时,坏事情会发生 要实现复制构造函数和复制赋值运算符并知道您已经正确地执行了这些操作,最简单的方法是使用。只有Foobar需要自定义复制构造函数、赋值运算符和析构函数。Foobase不需要,因为编译器提供的默认行为足够好 在Foobar的情况下,赋值运算符存在漏洞。在分配对象之前,您可以通过释

您的复制分配运算符的实现不正确。分配给它的对象泄漏了它的
base
指向的对象

您的默认构造函数也不正确:它使
base
var
都未初始化,因此无法知道两者是否有效,在析构函数中,当您调用
delete base;
时,坏事情会发生


要实现复制构造函数和复制赋值运算符并知道您已经正确地执行了这些操作,最简单的方法是使用。

只有
Foobar
需要自定义复制构造函数、赋值运算符和析构函数。
Foobase
不需要,因为编译器提供的默认行为足够好

Foobar
的情况下,赋值运算符存在漏洞。在分配对象之前,您可以通过释放对象来轻松修复它,这应该已经足够好了。但是如果您向
Foobar
添加第二个指针成员,您将看到这正是事情变得复杂的时候。现在,如果您在分配第二个指针您需要正确地清理分配的第一个指针,以避免损坏或泄漏。当您添加更多指针成员时,事情会以多项式方式变得更加复杂

相反,您要做的是根据复制构造函数实现赋值运算符。然后,您应该根据非抛出交换函数实现复制构造函数。有关详细信息,请阅读复制和交换习惯用法


另外,
Foobar
的默认构造函数不会默认初始化成员。这是不好的,因为这不是用户所期望的。成员指针指向任意地址,int有任意值。现在如果使用构造函数创建的对象,您就非常接近未定义的行为非常简单的修补程序:

class Foobar
{
  int var;    
  std::unique_ptr<FooBase> base;

...
class Foobar
{
int-var;
std::唯一的ptr基;
...
这应该让你开始

底线是:

  • 不要在代码中调用
    delete
    (专家参见第2点)
  • 不要在代码中调用
    delete
    (你更清楚…)

  • +1要点复制和交换习惯用法对于确保对象保持一致状态的异常安全实现至关重要。析构函数
    ~Foobar()
    ?@Mahatma:
    ~Foobar()不会释放内存吗
    不会被调用;对象永远不会被销毁,它被分配给。@Mahatma如果你有一个垃圾收集器,就会调用析构函数,在这种情况下,析构函数会在一些不一定确定的时刻被调用,或者如果指针是一个智能指针。但是你没有垃圾收集器,而且指针是最确定的inly不智能。因此必须手动清理。当然,也可以使用智能指针,这是一个很好的主意。好的,因为我做了一个
    base=new Foobase(other.GetBaseValue());
    ,原始内存区
    base
    指向泄漏。但是,如果在新分配之前执行
    删除base;
    操作以释放原始内存,则会出现
    双重释放或损坏
    错误。如果在新分配之前执行
    删除base;
    操作以释放原始内存,则会获得
    双重释放或更正正常运行
    错误。我将研究这个习惯用法。我没有得到关于空默认构造函数问题的最后一部分。我应该把
    var=SOMEVALUE;
    base=NULL;
    放在那里吗?因为在我的示例中,我使用了参数化构造函数。新表达式中没有括号只会对具有ut构造函数,这里没有任何类型。使用至少一个用户定义的构造函数对类型进行默认初始化时,会生成对默认构造函数的调用。从字面上讲,默认构造函数不会默认初始化成员(由于没有ctor初始值设定项,因此在任何mem初始值设定项id中都不会提到它们,并且标准规定在这种情况下它们是默认初始化的)但是,默认的初始化代码< int >代码>状态未指定。取决于编译器提供的C++库的年龄,它可以是<代码> STD::Tr1::UnQuyJPPT…