无法理解编译器在复制构造函数上引发的错误消息

Unable to understand error messege raised by compiler on copy constructor

本文关键字:消息 错误 构造函数 复制 编译器      更新时间:2023-10-16
#include <iostream>
using namespace std;
class dummy
{
private:
int a,b,*p;
public:
void setdata(int x,int y,int z)
{
a=x;
b=y;
p=&z;
}
void showdata()
{
cout<<"a "<<a<<"b "<<b<<" pointer address c "<<&p<<endl;
}
dummy(dummy &d)
{
a=d.a;
b=d.b;
p=d.p;
cout<<"a "<<a<<"b "<<b<<" pointer address c "<<&p<<endl;
}
dummy(dummy &d)
{
d.a;b=d.b;p=d.p;
}
};
int main()
{
dummy d1;//error is here;
d1.setdata(3,4,5);
dummy d2=d1;
d2.showdata();
d1.showdata();
return 0;
}

引发的错误

:/root/copy deep shallow/main.cpp|15|error: 调用 'dummy::d ummy()' 没有匹配函数|

我无法理解为什么会引发错误消息以及此问题的解决方案是什么

该类没有默认构造函数,因为存在显式定义的复制构造函数

dummy(dummy &d){a=d.a;b=d.b;p=d.p;}

(使用参数const dummy &声明 should)

然而,在本声明中

dummy d1;

需要缺少的默认构造函数。

您必须显式定义默认构造函数。

考虑到例如这个成员函数

void setdata(int x,int y,int z)
{a=x;b=y;p=&z;}

导致未定义的行为,因为指针p在退出函数后将具有无效值,因为局部变量(参数)z将被销毁。

dummy()
{
}
dummy(dummy &d)
{
a=d.a;
b=d.b;
p=d.p;
cout<<"a "<<a<<"b "<<b<<" pointer address c "<<&p<<endl;
}

这将解决您的问题。

通过这种方式,您可以定义默认构造函数(第一个)和一个复制构造函数(第二个)

在您的代码中,您没有提供默认构造函数和两个复制构造函数,因此编译器会首先抱怨缺少构造函数,但是您什么时候才能解决由于模棱两可的复制构造函数而引发另一个错误(编译器会告诉您我不知道哪个调用)。

作为第三个错误,setData() 将导致 p 在破坏 z 后无效的未定义行为。

你的问题不在于复制构造函数,而在于默认构造函数。 每当用 C++ 编写类时,编译器都会生成一组默认函数,因此您不必显式键入它们。这些是:

  • 默认构造函数:dummy::dummy()
  • 复制构造函数:dummy::dummy(const dummy&)
  • 复制赋值运算符:dummy& dummy::operator=(const dummy&)
  • 析构函数:dummy::~dummy()

在 C++11 标准中,您还可以获得移动构造函数和移动赋值运算符,但这些在这里并不重要。

编译器会为您将这些添加到任何类中,但如果定义任何构造函数,它不会生成隐式默认构造函数

如果要使用默认构造函数(并且能够在代码中使用dummy d1;),请将以下构造函数定义添加到类中:

dummy(){}

或者更好,如果您使用 C++11 标准:

dummy() = default;

旁注:在这种情况下,您不需要显式复制构造函数。您的实现只是将每个字段的内容复制到新对象,因此隐式复制构造函数(由编译器生成)就足够了。