简体   繁体   English

Visual Studio链接器错误

[英]visual studio Linker Error

I am writing a simple Queue class (for exercise). 我正在编写一个简单的Queue类(用于练习)。 This Project consists of a simple integer Node Class, which Queue Class utilizes, and the Queue class it self. 该项目由一个简单的整数节点类(队列类使用)以及它自己的队列类组成。

During build I am getting 3 different linker errors in my c++ project, listed below: 在构建期间,我的c ++项目中遇到3个不同的链接器错误,如下所示:

  1. Error LNK2005 "public: __thiscall Node::Node(int)" (??0Node@@QAE@H@Z) already defined in fmQueue.obj Queue 错误LNK2005“ public:__thiscall Node :: Node(int)”(?? 0Node @@ QAE @ H @ Z)已经在fmQueue.obj队列中定义

  2. Error LNK2005 "public: __thiscall Node::Node(void)" (??0Node@@QAE@XZ) already defined in fmQueue.obj Queue 错误LNK2005“ public:__thiscall Node :: Node(void)”(?? 0Node @@ QAE @ XZ)已在fmQueue.obj队列中定义

  3. Error LNK1169 one or more multiply defined symbols found Queue 错误LNK1169找到一个或多个乘法定义的符号

I did look at where i am introducing my classes, however i dont understand where this isuue is coming from. 我确实看过我在介绍我的课程的地方,但是我不明白这个问题是从哪里来的。

My code: 我的代码:

Node.h: Node.h:

// Node.h
// 1-way linked node for use in simple integer Queue

#ifndef NODE_H
#define NODE_H

class Node
{
public:
    Node();
    Node(int);

    int data;
    Node *next;
};

Node::Node()
{
    data = -1;
    next = nullptr;
}

Node::Node(int x)
{
    data = x;
    next = nullptr;
}

#endif

fmQueue.h: fmQueue.h:

#ifndef _FMQUEUE_H
#define _FMQUEUE_H


#include <iostream>
#include "Node.h"

namespace fm
{
    class fmQueue
    {
        Node *_head, *_tail;
        void clearbuf();


    public:

        fmQueue();

        ~fmQueue();

        void deQueue(); // uses front to access data, or remove data
        void enQueue(int); // uses back to sort data, or add data
        void dumQueue();

        //int peek(); // get a copy of the front data without removing it

        bool isEmpty();

    };

}

#endif /* _FMQUEUE_H */

fmQueue.cpp: fmQueue.cpp:

#include "fmQueue.h"

using namespace fm;

//---------Private Methods--------
void fmQueue::clearbuf()
{
    _head = _tail = nullptr;
}

//--------Public Methods----------

fmQueue::fmQueue()
{
    clearbuf();
}

fmQueue::~fmQueue()
{
    clearbuf();
}

bool fmQueue::isEmpty()
{
    if (_head == _tail && _head == nullptr)
        return false;
    else
        return true;
}


void fmQueue::enQueue(int data1)
{
    Node *tempNode = new Node;

    tempNode->next = nullptr;
    tempNode->data = data1;

    if (_head == nullptr)
    {
        _head = tempNode;
        _tail = tempNode;
    }


    else
    {
        _tail->next = tempNode;
    }

    _tail = tempNode;
}

void fmQueue::deQueue()
{
    Node *tempNode = new Node;

    if (_head == nullptr)
        std::printf("NOOOOP, THE QUEUE IS EMPTY");

    else
    {
        tempNode = _head;

        _head = _head->next;
        std::cout << "the data dequeued is: " << tempNode->data; //add a print statment to see which node was deleted

        delete tempNode;


    }

}

void fmQueue::dumQueue()
{
    Node *tempNode = new Node;

    if (tempNode)
        while (tempNode->next != nullptr)
        {
            std::cout << "Queue :" << tempNode->data;

            tempNode = tempNode->next;
        }
    else
        std::cout << "Nothing to show";

}

main.cpp: main.cpp:

#include"fmQueue.h"

int main()
{
    fm::fmQueue my_queue;
    my_queue.enQueue(2);
    std::cout << "fiirst done" << std::endl;
    my_queue.enQueue(4);
    std::cout << "second done" <<std::endl;
    my_queue.dumQueue();
    std::cout << "show done" << std::endl;
    my_queue.deQueue();
    std::cout << "delete done" << std::endl;
    my_queue.dumQueue();
    std::cout << "show done" << std::endl;
    my_queue.deQueue();
    std::cout << "delete done" << std::endl;

    return 0;
}

It's a common problem that's caused by having an implementation in a header file. 这是一个常见问题,是由头文件中的实现引起的。
What happens is that your fmQueue.cpp compilation unit compiles, and defines the constructor functions. 发生的是您的fmQueue.cpp编译单元编译并定义了构造函数。 After that, the main.cp compiles and defines the same functions (because they are visible in the included header file). 之后,main.cp编译并定义相同的函数(因为它们在包含的头文件中可见)。
So when the linker tries to link the 2 compilation units together it detects the double definition. 因此,当链接器尝试将两个编译单元链接在一起时,它将检测到双重定义。

So, that's why you should implement functions in the .cpp file. 因此,这就是为什么您应该在.cpp文件中实现功能的原因。
Another solution would be to decouple the header dependency. 另一个解决方案是将标头依赖性解耦。 You can forward declare the Node class in the queue's header, and only actually include the header in the queue's cpp file. 您可以在队列的标题中转发声明Node类,而实际上仅将标题包含在队列的cpp文件中。

Instead of putting #include "node.h" inside the other headers, put it inside the .cpp. 不要将#include“ node.h”放在其他头文件中,而应将它放在.cpp文件中。

Then you must forward declare the type in fmQueue.h. 然后,您必须在fmQueue.h中向前声明类型。

// fmQueue.h

class Node;

namespace fm
{
class fmQueue
{
    Node *_head, *_tail;
    void clearbuf();

 .....

// fmQueue.cpp


 #include "fmQueue.h"
 #include "Node.h"
 ....

The compiler just needs to know that there will be a type 'class Node' at this time, it doesn't need to know any of the members or methods of Node. 编译器只需要知道此时将有一个“类Node”类型,就不需要知道Node的任何成员或方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM