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

Copy-Constructor - Compiler-Error C2040 and C2440

本文关键字:C2040 C2440 错误 编译器 构造函数 复制      更新时间:2023-10-16

我收到一些来自我的复制构造函数的编译器错误。我知道第一个错误是由于不兼容的操作数类型造成的,我只是不确定编写该代码的更好方法。第二个错误我完全不确定。为什么'='无法从节点*转换为节点*?

任何帮助或指导都将得到认可。

谢谢!

// 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;

因此,这个错误是一种非常令人困惑的方式,说你重新声明了变量tempPtr,并给了它一个不同的类型。但请注意,如果你写List*(tempPtr)它会说redefinition: different basic types,所以它似乎也与List不像Node*那样像指针有关(这就是"间接级别"位的来源(。C2440 是由于重新声明而发生的。您可以通过注释掉List(tempPtr);并查看代码将编译来确认这一点。但是,它将编译的事实并不是说它以任何方式是正确的。

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

问题#3是你疯狂地泄漏Node物体。执行这些行时:

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

Node* copyNode = new Node;
copyNode = tempPtr;

您正在分配Node对象,然后丢弃指向它们的指针。如果您尝试复制Node对象,则不是这样做的方法。你也需要一个复制构造函数。

这不是List类的正确复制构造函数中的所有内容,但它涵盖了您发布的代码的一些最大问题,尤其是这似乎是您遇到这两个错误的原因。

这种情况看起来像是你的某种误解和编译器错误的结合。

正式声明

 List(tempPtr);

必须由编译器解释为声明

 List tempPtr;

语言规范在 6.8 (C++03( 中明确指出,声明和功能强制表达之间的歧义必须以赞成或声明的方式解决。这意味着您那里拥有的是非法重新声明可变tempPtr。您之前已经使用其他类型声明了tempPtr

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

尽管如此,无论如何解释该语句(表达式或声明(,它在您的代码上下文中都没有意义。在任何一种情况下,它都会被破坏。所以,基本上,问题是:你到底想用这条List(tempPtr);线做什么?你的意图是什么?

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