为什么我在显式编写复制构造函数后得到垃圾值?
Why I'm getting garbage value after explicitly writing the 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;
}
在这里,当我没有显式地编写复制构造函数时,这个程序给出了正确的输出。但是在写了copy constructor之后输出的是垃圾值,我想知道为什么程序会产生垃圾值?
输出实例:
Normal constructor
Normal constructor
Normal constructor
The copy constructor is called
Normal constructor a = -1270468398
b = 32769
请告诉"what is happening after c3 = c1+2;
is executed?"
您忘记在复制构造函数中复制成员。如果您自己编写,则必须这样做。因为你没有默认初始化成员,在 int
的情况下,这意味着没有初始化发生,所以你有一个垃圾值。
你的复制构造函数应该是
Complex(const Complex &z) : a(z.a), b(z.b)
{
std::cout<<"\n The copy constructor is called ";
}
你还应该通过const&
把要复制的对象也带进去,这样你就可以复制临时对象了。 Complex(Complex &z)
做不到。
您没有在复制构造函数中初始化成员数据。
添加代码以初始化成员。
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 ";
}
将 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 对象上调用)
希望对您有所帮助。
在您的情况下,由于您没有任何要执行深复制的指针,因此编译器生成的复制构造函数就足够了。
为了提高可读性,在版本 >= 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= 函数被调用,temp 将被分配给C3。如果重载operator=,可以看到对它的调用
我有一个程序使用 + 运算符重载将两个复数相加。程序是:
#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;
}
在这里,当我没有显式地编写复制构造函数时,这个程序给出了正确的输出。但是在写了copy constructor之后输出的是垃圾值,我想知道为什么程序会产生垃圾值?
输出实例:
Normal constructor
Normal constructor
Normal constructor
The copy constructor is called
Normal constructor a = -1270468398
b = 32769
请告诉"what is happening after c3 = c1+2;
is executed?"
您忘记在复制构造函数中复制成员。如果您自己编写,则必须这样做。因为你没有默认初始化成员,在 int
的情况下,这意味着没有初始化发生,所以你有一个垃圾值。
你的复制构造函数应该是
Complex(const Complex &z) : a(z.a), b(z.b)
{
std::cout<<"\n The copy constructor is called ";
}
你还应该通过const&
把要复制的对象也带进去,这样你就可以复制临时对象了。 Complex(Complex &z)
做不到。
您没有在复制构造函数中初始化成员数据。
添加代码以初始化成员。
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 ";
}
将 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 对象上调用)
希望对您有所帮助。
在您的情况下,由于您没有任何要执行深复制的指针,因此编译器生成的复制构造函数就足够了。
为了提高可读性,在版本 >= 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= 函数被调用,temp 将被分配给C3。如果重载operator=,可以看到对它的调用