这是我编写的代码的简化版本:
#include <iostream>
class pos
{
public:
char (&board)[64];
pos(char (&arr)[64])
: board(arr)
{
*board = *arr;
}
void print();
};
void pos::print()
{
for (int y=0; y<8; y++)
{
for (int x=0; x<8; x++)
std::cout << (int) board[x + y*8] << " ";
std::cout << "\n";
}
}
int main()
{
char test[64] = {
0, 1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
2, 3, 4, 5, 6, 7, 8, 9,
3, 4, 5, 6, 7, 8, 9,10,
4, 5, 6, 7, 8, 9,10,11,
5, 6, 7, 8, 9,10,11,12,
6, 7, 8, 9,10,11,12,13,
7, 8, 9,10,11,12,13,14 };
pos p(test);
p.print();
std::cin.get();
return 0;
}
但如果我将pos
的所有实例更改为position
,我会收到错误:main.obj:错误LNK2005:&#34; public:void __thiscall position :: print(void)& #34; (?print @ position @@ QAEXXZ)已在position.obj中定义
1&gt; D:\ Programming \ Test \ Debug \ Test.exe:致命错误LNK1169:找到一个或多个多重定义的符号
奇怪的是,该类曾经被命名为position
并且编译得很好,直到我对它处理board
数组的方式做了一些更改。有人可以解释为什么我会收到此错误吗?
更新
现在,这个类的命名并不重要,我得到了同样的错误。我创建了一个新的MSVC ++项目,复制了源文件,并进行了新的构建。同样的错误。这是实际的代码,而不是简洁的版本。
的main.cpp
#include <iostream>
#include "position.cpp"
int main()
{
char test[64] = { // Simple mate test position; TODO: move to test suite
OO,BK,OO,OO,OO,OO,OO,OO,
OO,OO,OO,OO,OO,OO,OO,WR,
OO,WK,OO,OO,OO,OO,OO,OO,
OO,OO,OO,OO,OO,OO,OO,OO,
OO,OO,OO,OO,OO,OO,OO,OO,
OO,OO,OO,OO,OO,OO,OO,OO,
OO,OO,OO,OO,OO,OO,OO,OO,
OO,OO,OO,OO,OO,OO,OO,OO };
position pos(test);
pos.print();
std::cin.get();
return 0;
}
position.cpp
#include <iostream>
// Board-centric representation; pass as 64-byte array
#define WK 0x0 // White King
#define WQ 0x1 // White Queen
#define WR 0x2 // White Rook
#define WB 0x3 // White Bishop
#define WN 0x4 // White Knight
#define WP 0x5 // White Pawn
#define BK 0x6 // Black King
#define BQ 0x7 // Black Queen
#define BR 0x8 // Black Rook
#define BB 0x9 // Black Bishop
#define BN 0xA // Black Knight
#define BP 0xB // Black Pawn
// 0xC: unused
// 0xD: unused
// 0xE: unused
#define OO 0xF // Empty
class position
{
public:
char (&board)[64];
position(char (&arr)[64]) // TODO: 'board' dies if the variable passed through 'arr' dies. Allocating memory might fix this. See 'new' and 'shared_ptr'.
: board(arr)
{
*board = *arr;
}
void print();
};
void position::print()
{
for (int y=0; y<8; y++)
{
for (int x=0; x<8; x++)
std::cout << (int) board[x + y*8] << " ";
std::cout << "\n";
}
}
(我正在写一个程序来弄清楚简单的国际象棋游戏结束。)
正如您所看到的,position::print()
仅在一个地方定义,与错误消息相反......除非我严重忽视某些内容。这很早。
答案 0 :(得分:2)
您不应该在主文件中#include "position.cpp"
,而应该是position
类的头文件。
答案 1 :(得分:2)
问题是您正在编译position.cpp
中包含的代码,并且您正在尝试将已编译的代码链接到一个文件中。
问题是由main.cpp
中的这一行引起的:
#include "position.cpp"
您要包含C ++源文件,而不是标题。这意味着position.cpp
中的所有代码都包含在main.cpp
中,然后编译生成的文件。然后,您可以自己编译position.cpp
。
尝试包含position.h
- 如果还没有这样的标题,请定义它。另一种解决方法是不将position.cpp
添加到要编译的源列表中。
答案 2 :(得分:1)
您在main.cpp中包含postition.cpp,可能您的构建系统也单独构建position.cpp,然后链接器会找到您类的多个定义。
你应该制作一个单独的标题并在msvc上添加包含警戒,#pragma once
答案 3 :(得分:0)
错误消息指出您有void position::print()
的两个定义,一个位于main.cpp
,另一个位于position.cpp
。
答案 4 :(得分:0)
这不是保留字,而是position.cpp
中你的名称。您使用相同的名称,但在main.cpp
中具有不同的含义。
答案 5 :(得分:0)
编译器/链接器处理翻译单元,而不是文件。您可以在一个文件(position.cpp)中定义position :: print。但是,自从您编写#include "position.cpp"
以来,该定义实际上存在于两个翻译单元中。您违反了ODR(一个定义规则)。