visual studio 链接器错误
visual studio Linker Error
我正在写一个简单的队列class(练习)。该项目包含一个简单的整数节点 Class,队列 Class 使用它,队列 class 它自己。
在构建过程中,我的 C++ 项目出现了 3 个不同的链接器错误,如下所列:
错误 LNK2005 "public: __thiscall Node::Node(int)" (??0Node@@QAE@H@Z)
已在 fmQueue.obj 队列
中定义
错误 LNK2005 "public: __thiscall Node::Node(void)" (??0Node@@QAE@XZ)
已在 fmQueue.obj 队列
中定义
错误 LNK1169 找到一个或多个多次定义的符号 Queue
我确实看过我介绍我的 classes 的地方,但是我不明白这个问题是从哪里来的。
我的代码:
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;
}
这是一个常见问题,由 header 文件中的实现引起。
发生的事情是您的 fmQueue.cpp 编译单元编译并定义了构造函数。
之后,main.cp 编译并定义相同的函数(因为它们在包含的 header 文件中可见)。
因此,当 linker 尝试 link 将 2 个编译单元放在一起时,它会检测到双重定义。
所以,这就是您应该在 .cpp 文件中实现功能的原因。
另一种解决方案是解耦 header 依赖项。您可以在 queue 的 header 中转发声明节点 class,并且实际上只在 queue 的 cpp 文件中包含 header。
与其将#include "node.h" 放入另一个 headers 中,不如将其放入 .cpp.
那么你必须在fmQueue.h中转发声明类型。
// fmQueue.h
class Node;
namespace fm
{
class fmQueue
{
Node *_head, *_tail;
void clearbuf();
.....
// fmQueue.cpp
#include "fmQueue.h"
#include "Node.h"
....
此时编译器只需要知道会有一个类型'class Node'即可,不需要知道Node的任何成员或方法
我正在写一个简单的队列class(练习)。该项目包含一个简单的整数节点 Class,队列 Class 使用它,队列 class 它自己。
在构建过程中,我的 C++ 项目出现了 3 个不同的链接器错误,如下所列:
错误 LNK2005 "public: __thiscall Node::Node(int)" (??0Node@@QAE@H@Z) 已在 fmQueue.obj 队列
中定义
错误 LNK2005 "public: __thiscall Node::Node(void)" (??0Node@@QAE@XZ) 已在 fmQueue.obj 队列
中定义
错误 LNK1169 找到一个或多个多次定义的符号 Queue
我确实看过我介绍我的 classes 的地方,但是我不明白这个问题是从哪里来的。
我的代码:
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;
}
这是一个常见问题,由 header 文件中的实现引起。
发生的事情是您的 fmQueue.cpp 编译单元编译并定义了构造函数。
之后,main.cp 编译并定义相同的函数(因为它们在包含的 header 文件中可见)。
因此,当 linker 尝试 link 将 2 个编译单元放在一起时,它会检测到双重定义。
所以,这就是您应该在 .cpp 文件中实现功能的原因。
另一种解决方案是解耦 header 依赖项。您可以在 queue 的 header 中转发声明节点 class,并且实际上只在 queue 的 cpp 文件中包含 header。
与其将#include "node.h" 放入另一个 headers 中,不如将其放入 .cpp.
那么你必须在fmQueue.h中转发声明类型。
// fmQueue.h
class Node;
namespace fm
{
class fmQueue
{
Node *_head, *_tail;
void clearbuf();
.....
// fmQueue.cpp
#include "fmQueue.h"
#include "Node.h"
....
此时编译器只需要知道会有一个类型'class Node'即可,不需要知道Node的任何成员或方法