C++ 复制构造函数-编译器错误C2040和C2440

C++ 复制构造函数-编译器错误C2040和C2440,c++,compiler-errors,copy-constructor,C++,Compiler Errors,Copy Constructor,我得到了一些编译器错误,这些错误源于我的复制构造函数。我知道第一个错误是由于不兼容的操作数类型造成的,我只是不确定是否有更好的方法来编写该代码。第二个错误我一点也不确定。为什么'='不能从Node*转换到Node* 任何帮助或指导都将受到感谢 谢谢 // Copy-Constructor List::List(const List& theList) { Node* tempPtr = new Node; tempPtr = theList.first; //error

我得到了一些编译器错误,这些错误源于我的复制构造函数。我知道第一个错误是由于不兼容的操作数类型造成的,我只是不确定是否有更好的方法来编写该代码。第二个错误我一点也不确定。为什么
'='
不能从Node*转换到Node*

任何帮助或指导都将受到感谢

谢谢

// Copy-Constructor
List::List(const List& theList)
{
    Node* tempPtr = new Node;
    tempPtr = theList.first;

//error C2040: 'tempPtr' : 'List' differs in levels of indirection from 'Node *'
    List(tempPtr);

    while (tempPtr != NULL)
    {
        Node* copyNode = new Node;

//error C2440: '=' :cannot convert from 'Node *' to 'Node *'
        copyNode = tempPtr;

        tempPtr = tempPtr->getNext();
        nodeListTotal++;
    }
}
下面是我的构造函数和析构函数

List::List():first(0), last(0), nodeListTotal(0)
{
}

// Destructor
List::~List()
{
    Node* currentNode = first;

    while(currentNode != NULL) 
    {
        Node* temp = currentNode;
        currentNode = currentNode->getNext();
        delete temp;
    }
}

这里有几个问题。首先,C2040和C2440的类型相同。根据我的发现,声明中允许使用括号,因此声明:

List(tempPtr);
显然相当于:

List tempPtr;
因此,如果说您重新声明了变量
temptr
,并且为其指定了不同的类型,那么这个错误是一种非常令人困惑的说法。但是请注意,如果您编写了
List*(temptr)
,它会说
重新定义:不同的基本类型
,因此它似乎也与以下事实有关:
List
不像
Node*
那样是指针(这就是“间接级别”位的来源)。C2440由于重新声明而发生。您可以通过注释掉
List(temptr)来确认这一点并查看代码将编译。然而,它将编译的事实并不是说它在任何方面都是正确的

问题#2是,这里没有显示一个构造函数,它接受一个
节点*
,即使有一个,也不是正确的调用方法。我不完全确定你想用它做什么

问题3是你正在疯狂地泄漏
节点
对象。执行这些行时:

Node* tempPtr = new Node;
tempPtr = theList.first;

您正在分配
节点
对象,然后丢弃指向它们的指针。如果您试图复制
节点
对象,则这不是执行此操作的方法。你也需要一个复制构造函数


对于
列表
类来说,这并不是进入正确副本构造函数的全部内容,但它涵盖了您发布的代码的一些最大问题,尤其是这似乎就是为什么会出现这两个错误的原因。

这种情况看起来像是您的某种误解和编译器错误的组合

正式声明

 List(tempPtr);
必须由编译器解释为声明

 List tempPtr;
中的语言规范在6.8(C++03)中明确指出,声明和函数强制转换表达式之间的歧义必须以赞成或声明的方式解决。这意味着您所拥有的是对变量
temptr
的非法重新声明。您之前已使用其他类型声明了
temptr

但是,编译器发出的错误消息似乎表明编译器将其解释为函数强制转换表达式(而不是声明)。此表达式尝试从
节点*
类型的指针
temptr
创建类型为
列表
的无名临时对象。然后立即销毁该临时对象(如果成功创建)。但是,类
List
没有可以从
节点*
指针构造它的构造函数。这就是编译器告诉你的。类
列表
只有一个单参数构造函数,它接受
常量列表&
,而您提供了一个
节点*
。编译器告诉您,它无法将
节点*
转换为
列表
来调用该构造函数

尽管如此,无论如何解释该语句(表达式或声明),在代码上下文中都没有意义。这两种情况都是坏的。所以,基本上,问题是:你到底想用
列表(temptr)做什么行?你的意图是什么


第二个错误可能是由第一个错误引起的。

我对第一行“List(tempPtr);”很好奇你在哪里定义这个构造函数?可能是该错误导致了第二个错误。更重要的是,你有一个非常明显的漏洞。在循环中分配copyNode,然后尝试用tempPtr覆盖它。为什么?这是我第一次尝试建立一个链表,而复制构造函数把我甩了。看起来我没有在构造函数中定义
List(temptr)
,我正在尝试复制列表中的第一个节点,这就是为什么我要用temptr覆盖copyNode。你打算用
List(temptr)做什么?即使您有一个
列表(Node*)
构造函数,调用也不太可能执行您想要执行的操作;tempPtr=列表第一-您正在分配一个新节点,然后在列表中用
中的
首先覆盖它。我并不是说编译器将其解释为强制转换(这是我最初的想法)是错误的,但是,即使
列表
有一个节点*
,也会出现错误,并且文本是相同的-我试过了。@Joel:说得好。我也试过了,事实上,添加相应的构造函数没有帮助。此外,删除变量名周围的
()
不会更改错误消息。这可能意味着编译器将其正确解释为声明,但它发出的错误消息有点误导和/或混淆。底线是代码是无效的,所以您试图通过这一行做什么的问题仍然存在。
 List tempPtr;