问题描述
我有一个问题,我无法解决它(使用谷歌)。作为练习,我写了一个关于国际象棋的程序。 有一个通用的片断类:
pieces.h :
#ifndef PIECES_H
#define PIECES_H
[...]
class piece{
public:
bool dark; //0 = light,1 = dark
virtual std::vector<position> sovereign_movement();
types identify; // enum types = {pawn,knight,king,etc...}
position pos;
std::vector<position> horizontal(position a);
std::vector<position> vertical(position a);
std::vector<position> plus90(position a); //basic moves
std::vector<position> minus90(position a);
std::vector<position> Lshape(position a);
piece() : identify(non),pos(position(1,1)) {}
virtual ~piece() {}
};
class Pawn : public piece{
public:
Pawn() { identify = pawn; }
std::vector<position> sovereign_movement() {std::vector<position> sol; return sol;}
~Pawn() = default;
};
[...]
#endif //PIECES_H
还有我的 main 用于测试:
#include "pieces.h"
int main()
{
piece a;
vector<position> test = a.horizontal();
for(unsigned int i=0; i<test.size() ;i++)
{
cout << test[i].Pconvert() << endl; /// position::Pconvert() just make string
}
return 0;
}
#include "pieces.h"
#ifndef PIECES_H
#define PIECES_H
std::vector<position> piece::horizontal(position a){
std::vector<position> sol;
for(int i = 1;i<=8;i++){
sol.push_back(position(i,a.y));
if(i==a.x){sol.pop_back();}
}
return sol;
}
[...]
#endif //PIECES_H
为此,我在头文件中为构造函数和析构函数获取了 undefined reference to piece::horizontal(position)
和 undefined reference to vtable for piece
。
如果我执行析构函数摘要 (virtual ~piece() = 0
),我会得到:
error: cannot declare variable 'a' to be of abstract type 'piece',because the following functions are pure within 'piece': virtual piece::~piece()
在那之后,我编写了所有派生类的默认析构函数,但写得一样。在此之后,我以这种方式修改我的主要内容(Pawn
是 piece
的派生类之一):
int main()
{
piece* a = new Pawn();
vector<position> test = a->horizontal(a->pos);
for(unsigned int i=0;i<test.size();i++){
cout << test[i].Pconvert() << endl;
}
return 0;
}
然后我得到:undefined reference to 'piece::horizontal(position)'
和 .h 中对碎片的析构函数的未定义引用,因此圆形已关闭。
有人可以帮我吗? 谢谢
解决方法
当您包含头文件时,该文件的内容会替换 #include
行。所以当 pieces.cpp
像这样开始时:
#include "pieces.h"
#ifndef PIECES_H
#define PIECES_H
std::vector<position> piece::horizontal(position a){
std::vector<position> sol;
for(int i = 1;i<=8;i++){
sol.push_back(position(i,a.y));
if(i==a.x){sol.pop_back();}
}
return sol;
}
#endif //PIECES_H
预处理器处理完#include
后变成下面这样。
#ifndef PIECES_H
#define PIECES_H
class piece{
public:
bool dark; //0 = light,1 = dark
virtual std::vector<position> sovereign_movement();
types identify; // enum types = {pawn,knight,king,etc...}
position pos;
std::vector<position> horizontal(position a);
std::vector<position> vertical(position a);
std::vector<position> plus90(position a); //basic moves
std::vector<position> minus90(position a);
std::vector<position> Lshape(position a);
piece() : identify(non),pos(position(1,1)) {}
virtual ~piece() {}
};
#endif //PIECES_H
#ifndef PIECES_H
#define PIECES_H
std::vector<position> piece::horizontal(position a){
std::vector<position> sol;
for(int i = 1;i<=8;i++){
sol.push_back(position(i,a.y));
if(i==a.x){sol.pop_back();}
}
return sol;
}
#endif //PIECES_H
接下来,考虑 PIECES_H
宏。我会在处理过程中注释掉预处理行。
// #ifndef PIECES_H -- PIECES_H is not defined yet,so proceed.
// #define PIECES_H -- now PIECES_H is defined.
class piece{
public:
bool dark; //0 = light,1)) {}
virtual ~piece() {}
};
// #endif //PIECES_H -- end of the earlier #ifndef
// #ifndef PIECES_H -- PIECES_H is still defined from earlier. So skip ahead.
// All these lines are omitted from compilation
// #endif //PIECES_H -- end of the earlier #ifndef
预处理器只是撕掉了 pieces.cpp
的内容,因为头保护的误用。 Header 守卫属于 header(另见 A: C++ Header Guard Syntax and Header Placement)。将它们从您的源文件中取出,它应该可以按预期编译。