C++编译器错误:没有匹配的调用函数

Zia*_*man 2 c++ oop

请查看以下代码.这有什么问题?编译器给出了这个错误:

在复制构造函数person::person(person&)': No matching function for call toperson :: copy(char*&,char*&)'候选者是:void person :: copy(char*&,const char*&)"

这是代码:

class person
{
  public:
    person();
    person(person &);

  private:
    void copy(char*&,const char*&);
    char* name, *fathername,* address;
};

void person::copy( char*& n, const char*& p)
{
  int result;
  result=strcmp(n,p);
  if(result!=0)
  {
    n=new char[strlen(p)+1];
    strcpy(n,p);
    n[strlen(p)]='\0';
  }
}
person::person(person &object)
{
  copy(name,object.name);
  copy(fathername,object.fathername);
  copy(address, object.address);
}
Run Code Online (Sandbox Code Playgroud)

从这个问题的答案来看,到目前为止我所理解的是:编译器不允许将引用转换为常量引用,因为引用已经是常量.它们不能指向像指针一样的不同内存位置.我对吗?

Kor*_*icz 10

这不会更好吗?

class person
{
private:
  std::string name;
  std::string fathername
  std::string address;
};

// constructor and copy constructor autogenerated!
Run Code Online (Sandbox Code Playgroud)

这种方式更像是"C++";).

  • 为什么要这么做.如果所有成员变量都是std :: string,那么编译生成的拷贝构造函数就可以正常工作,你不应该自己编写. (7认同)
  • 你很好,但问题的本质是不同的 (2认同)

Mar*_*ork 7

除非您计划更改指针,否则不应将引用传递给指针:

更改:

void person::copy( char*& n, const char*& p) 
Run Code Online (Sandbox Code Playgroud)

void person::copy( char* n, const char* p) 
Run Code Online (Sandbox Code Playgroud)

这是因为p是对特定类型的引用.
您传递的对象不是确切的类型,因为它是一个参考,他们无法转换它.

我在上面建议的改变允许"指向const char的指针"(p),从而允许通过'p'只读访问元素.现在,"指向char的指针"允许对数据进行读/写访问,因此允许将其转换为"指向const char的指针",因为我们只是限制了允许的行为.

您发布的代码存在一系列其他问题.
你想让我们列出它们吗?

我现在不做.我按照我的日程安排.

问题:

1:每次调用复制都会泄漏:

if(result!=0)
{
    n=new char[strlen(p)+1];   // What happned to the old n?
Run Code Online (Sandbox Code Playgroud)

2:使用默认赋值运算符.

person a;
person b;
a = b; // a.name == b.name etc all point at the same memory location.
       // Though because you do not delete anything in the destructor
       // it is technically not an issue yet.
Run Code Online (Sandbox Code Playgroud)

3:您完成了在析构函数中删除已分配的成员.

{
     person  a;
} // A destructor called. You leak all the member here.
Run Code Online (Sandbox Code Playgroud)

4:strcpy()已经复制了终止'\ 0'字符.

5:如果调用new抛出异常.你会泄漏内存.

copy(name,object.name); 
copy(fathername,object.fathername);   // If new throws in here.
                                      // Then the this.name will be leaked.
Run Code Online (Sandbox Code Playgroud)

使用C-String正确地执行此操作非常困难,即使是C++专家也会在正确执行此操作时遇到问题.这就是为什么C++专家会使用std :: string而不是C-String.如果必须使用C-Strings,那么应该将C-String包装在另一个类中,以保护它免受异常的问题.