-std=c++11 未定义对 vtable 的引用 -- 国际象棋
-std=c++11 undefined reference to vtable for -- Chess
我有一个问题,但我无法解决(google)。作为练习,我写了一个关于国际象棋的程序。
有一般片class:
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;
}
我有一个 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
为此,我在头文件中得到 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()
之后,我编写了所有派生的 classes 的默认析构函数,但写的是一样的。在此之后,我以这种方式修改我的主要内容(Pawn
是 piece
的派生 classes 之一):
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 中对 piece 的析构函数的未定义引用,因此 round 被关闭。
有人可以帮助我吗?
谢谢
当您包含 header 文件时,该文件的内容将替换 #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
pre-processor处理完#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 = 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 -- 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
由于 header 守卫的 mis-use,预处理器刚刚删除了 pieces.cpp
的内容。 Header 守卫属于 header(另见 A: C++ Header Guard Syntax and Header Placement)。将它们从您的源文件中取出,它应该按预期编译。
我有一个问题,但我无法解决(google)。作为练习,我写了一个关于国际象棋的程序。 有一般片class:
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;
}
我有一个 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
为此,我在头文件中得到 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()
之后,我编写了所有派生的 classes 的默认析构函数,但写的是一样的。在此之后,我以这种方式修改我的主要内容(Pawn
是 piece
的派生 classes 之一):
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 中对 piece 的析构函数的未定义引用,因此 round 被关闭。
有人可以帮助我吗? 谢谢
当您包含 header 文件时,该文件的内容将替换 #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
pre-processor处理完#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 = 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 -- 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
由于 header 守卫的 mis-use,预处理器刚刚删除了 pieces.cpp
的内容。 Header 守卫属于 header(另见 A: C++ Header Guard Syntax and Header Placement)。将它们从您的源文件中取出,它应该按预期编译。