为什么我在显式编写Copy Constructor后得到了垃圾值?

时间:2016-02-19 16:19:39

标签: c++ class copy-constructor

我有一个程序,使用+运算符重载添加两个复数。该计划是:

#include<iostream>
class Complex
{
  int a, b;
  public:
  Complex()
  {
    std::cout<<"\n Normal constructor ";
  }
  void setData(int x, int y)
  {
    a = x; b = y;
  }
  void showData()
  {
    std::cout<<"a = "<<a<<std::endl<<"b = "<<b<<std::endl;
  }
  Complex operator + (Complex c)
  {
    Complex temp;
    temp.a = a + c.a;
    temp.b = b + c.b;
    return temp;
  }
  Complex(Complex &z)
  {
    std::cout<<"\n The copy constructor is called ";
  }
};
int main()
{
  Complex c1, c2, c3;
  c1.setData(2, 3);
  c2.setData(4, 5);
  c3 = c1+c2;
  c3.showData();
  return 0;
}

这里当我没有明确地写复制构造函数时,这个程序正在给出正确的输出。但在编写复制构造函数后,输出是垃圾值,我想知道为什么程序会产生垃圾值?

输出实例:

Normal constructor 
 Normal constructor 
 Normal constructor 
 The copy constructor is called 
 Normal constructor a = -1270468398
b = 32769

请告诉我“c3 = c1+2;执行后会发生什么?”

4 个答案:

答案 0 :(得分:4)

您忘记复制复制构造函数中的成员。如果你自己写,你必须这样做。由于您没有对成员进行默认初始化,并且在int的情况下,这意味着不会进行初始化,因此您有垃圾值。

您的副本构造函数应该是

Complex(const Complex &z) : a(z.a), b(z.b)
{
    std::cout<<"\n The copy constructor is called ";
}

您还应该通过const&接受要复制的对象,以便您可以复制临时对象。 Complex(Complex &z)无法做到这一点。

答案 1 :(得分:2)

您没有在复制构造函数中初始化成员数据。

添加代码以初始化成员。

Complex(Complex &z) : a(z.a), b(z.b)
{
   std::cout<<"\n The copy constructor is called ";
}

此外,您应该将参数设置为const&类型的复制结构。

Complex(Complex const& z) : a(z.a), b(z.b)
{
   std::cout<<"\n The copy constructor is called ";
}

答案 2 :(得分:1)

c2传递给operator +时会调用您的复制构造函数。

有两种方法可以解决您的问题(但两者都应该修复):

operator+应该使用const引用而不是对象的副本:

Complex operator + (const Complex &c)

您的复制构造函数应该真正复制对象(除了将const引用作为参数):

Complex(const Complex &z) : a (z.a), b(z.b)

您的代码还需要做一些其他评论

  • 首先,我希望它只是一个练习,因为std::complex存在
  • 您的默认构造函数应该初始化成员
  • setData / showData似乎有误,您应该有隐藏内部的有意义的访问者(复杂可以用实部/虚部表示,但也可以用模块/参数等表示......)
  • showData应该是const(它不修改对象,它应该可以在const对象上调用)

我希望这会有所帮助。

答案 3 :(得分:0)

在您的情况下,由于您没有任何要执行深层复制的指针,编译器生成的复制构造函数就足够了。

为了更具可读性,如果版本为&gt; = c ++ 11,您可以明确地使用它

Complex(Complex const&) = default;

要回答你的问题,当“c3 = c1 + c2;”

时会发生什么

函数“operator +”将在C1对象上调用,所以这里C2将被复制到参数“Complex c”。所以你得到了名为

的拷贝构造函数

就像这样可视化

Comlex operator+(Complex c(c2)/* copy constructor is called here*/)
{
    ...
    return temp.
}

然后调用operator = function并将temp分配给C3。如果你重载operator =,你可以看到对它的调用