簡體   English   中英

Visual Studio鏈接器錯誤

[英]visual studio Linker Error

我正在編寫一個簡單的Queue類(用於練習)。 該項目由一個簡單的整數節點類(隊列類使用)以及它自己的隊列類組成。

在構建期間,我的c ++項目中遇到3個不同的鏈接器錯誤,如下所示:

  1. 錯誤LNK2005“ public:__thiscall Node :: Node(int)”(?? 0Node @@ QAE @ H @ Z)已經在fmQueue.obj隊列中定義

  2. 錯誤LNK2005“ public:__thiscall Node :: Node(void)”(?? 0Node @@ QAE @ XZ)已在fmQueue.obj隊列中定義

  3. 錯誤LNK1169找到一個或多個乘法定義的符號

我確實看過我在介紹我的課程的地方,但是我不明白這個問題是從哪里來的。

我的代碼:

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:

#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:

#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:

#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;
}

這是一個常見問題,是由頭文件中的實現引起的。
發生的是您的fmQueue.cpp編譯單元編譯並定義了構造函數。 之后,main.cp編譯並定義相同的函數(因為它們在包含的頭文件中可見)。
因此,當鏈接器嘗試將兩個編譯單元鏈接在一起時,它將檢測到雙重定義。

因此,這就是為什么您應該在.cpp文件中實現功能的原因。
另一個解決方案是將標頭依賴性解耦。 您可以在隊列的標題中轉發聲明Node類,而實際上僅將標題包含在隊列的cpp文件中。

不要將#include“ node.h”放在其他頭文件中,而應將它放在.cpp文件中。

然后,您必須在fmQueue.h中向前聲明類型。

// fmQueue.h

class Node;

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

 .....

// fmQueue.cpp


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

編譯器只需要知道此時將有一個“類Node”類型,就不需要知道Node的任何成員或方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM