对参数的构造函数的未定义引用
undefined reference to constructor for argument
晚上好
我的构造函数有一个小问题。我正在尝试为我的棋盘的不同可能玩法构建一棵树(之后进行 DepthFirstSearch)。在我的节点 class 构造函数中,我想将当前板复制为树的叶子。但是当我尝试使用 Board class 实例作为 Node 构造函数的参数时,出现错误 "undefined reference to `Board::Board()'|"。
如果你知道如何正确地做到这一点,我正在倾听,我真的没有看到任何问题:(
这是我的 class 节点:
class Node
{
private :
Board state;
list<Node> sons;
public :
Node(Board&);
void addNode(Board&);
};
在执行节点构造函数时,我这样做了:
Node::Node(Board& tab)
{
state = tab;
sons = NULL;
}
我的董事会 class 是:
class Board {
private :
int** tab;
int nbline;
int nbcolumn;
Position emptyspot;
public :
Board(int, int, Play&); // initialised with random positions
Board(int, int); // just the good size, no values inside. Node::node during constructor.
void setValue(Position&, int);
void setNbline(int m);
void setNbcolumn(int n);
int getValue(Position&);
int getNbline();
int getNbcolumn();
int getEmptyline();
int getEmptycolumn();
void setEmptySpot(Position&);
Position& getEmptySpot();
Board& operator=(Board& source);
};
编辑:由于人们的询问,这里是 Board 的构造函数:
Board::Board(int m, int n, Play& jeu) : tab{new int*[m]}, nbline{m}, nbcolumn{n}, emptyspot{n-1,m-1}{
int x(1);
for (int i = 0; i < m; ++i){
tab[i] = new int[n];
for(int j = 0; j < n; ++j) {
tab[i][j] = x; x++;}}
tab[n-1][m-1]=0;
x=0;
while (x!=1000)
{
int numbers[] = { UP, DOWN, LEFT, RIGHT };
int length = sizeof(numbers) / sizeof(int);
int randomNumber = numbers[rand() % length];
jeu.moves(*this, randomNumber);
x++;
}
}
Board::Board(int m, int n) : tab{new int*[m]}, nbline{m}, nbcolumn{n}, emptyspot{n-1,m-1} {
for (int i = 0; i < m; ++i){
tab[i] = new int[n];
for(int j = 0; j < n; ++j) {
tab[i][j] = 0;}}
}
由于 state
不在 Node
的构造函数初始化列表中,它将使用其默认构造函数创建。问题是,Board
没有默认构造函数。要解决此问题,请使用初始化列表。这假定 Board
具有适当的复制构造函数。
Node::Node(const Board& tab)
: state(tab)
{
}
我把参数设为const。我还删除了列表分配。我不知道将 NULL 分配给列表是什么意思,但如果它是 std::list
那么它的默认构造函数无论如何都会将它创建为空。
这并不奇怪。在 Node::Node(Board& tab)
中,状态在您进行赋值之前默认初始化。由于您没有明确地执行此操作,因此编译器会调用未定义的 Board::Board()
。将 Node::Node()
更改为:
Node::Node(Board& tab)
: state(tab)
, sons(NULL)
{
}
请记住,必须在执行构造函数的主体之前完全初始化所有成员。因此 类 包含 类 的引用成员或实例,但没有定义 default/copy 构造函数,必须始终通过初始化列表初始化它们。
另外,如果你在Board
中定义了operator=()
,也定义复制构造函数(记住Rule of Three):
class Board
{
//...
Board(const Board&)
{
//make a copy
}
};
编辑
我觉得Board的拷贝构造函数应该这样实现:
Board(const Board& origin)
: tab(NULL)
, nbline(origin.nbline)
, nbcolumn(origin.nbcolumn)
, emptyspot(origin.emptyspot)
{
this->tab = new int*[this->nbline];
for (int i = 0; i < m; ++i)
this->tab[i] = new int[this->nbcolumn];
//Tab contains int's, so let's do simple memcpy()
memcpy(this->tab, origin.tab, sizeof(int) * this->nbline * this->nbcolumn);
}
晚上好
我的构造函数有一个小问题。我正在尝试为我的棋盘的不同可能玩法构建一棵树(之后进行 DepthFirstSearch)。在我的节点 class 构造函数中,我想将当前板复制为树的叶子。但是当我尝试使用 Board class 实例作为 Node 构造函数的参数时,出现错误 "undefined reference to `Board::Board()'|"。
如果你知道如何正确地做到这一点,我正在倾听,我真的没有看到任何问题:(
这是我的 class 节点:
class Node
{
private :
Board state;
list<Node> sons;
public :
Node(Board&);
void addNode(Board&);
};
在执行节点构造函数时,我这样做了:
Node::Node(Board& tab)
{
state = tab;
sons = NULL;
}
我的董事会 class 是:
class Board {
private :
int** tab;
int nbline;
int nbcolumn;
Position emptyspot;
public :
Board(int, int, Play&); // initialised with random positions
Board(int, int); // just the good size, no values inside. Node::node during constructor.
void setValue(Position&, int);
void setNbline(int m);
void setNbcolumn(int n);
int getValue(Position&);
int getNbline();
int getNbcolumn();
int getEmptyline();
int getEmptycolumn();
void setEmptySpot(Position&);
Position& getEmptySpot();
Board& operator=(Board& source);
};
编辑:由于人们的询问,这里是 Board 的构造函数:
Board::Board(int m, int n, Play& jeu) : tab{new int*[m]}, nbline{m}, nbcolumn{n}, emptyspot{n-1,m-1}{
int x(1);
for (int i = 0; i < m; ++i){
tab[i] = new int[n];
for(int j = 0; j < n; ++j) {
tab[i][j] = x; x++;}}
tab[n-1][m-1]=0;
x=0;
while (x!=1000)
{
int numbers[] = { UP, DOWN, LEFT, RIGHT };
int length = sizeof(numbers) / sizeof(int);
int randomNumber = numbers[rand() % length];
jeu.moves(*this, randomNumber);
x++;
}
}
Board::Board(int m, int n) : tab{new int*[m]}, nbline{m}, nbcolumn{n}, emptyspot{n-1,m-1} {
for (int i = 0; i < m; ++i){
tab[i] = new int[n];
for(int j = 0; j < n; ++j) {
tab[i][j] = 0;}}
}
由于 state
不在 Node
的构造函数初始化列表中,它将使用其默认构造函数创建。问题是,Board
没有默认构造函数。要解决此问题,请使用初始化列表。这假定 Board
具有适当的复制构造函数。
Node::Node(const Board& tab)
: state(tab)
{
}
我把参数设为const。我还删除了列表分配。我不知道将 NULL 分配给列表是什么意思,但如果它是 std::list
那么它的默认构造函数无论如何都会将它创建为空。
这并不奇怪。在 Node::Node(Board& tab)
中,状态在您进行赋值之前默认初始化。由于您没有明确地执行此操作,因此编译器会调用未定义的 Board::Board()
。将 Node::Node()
更改为:
Node::Node(Board& tab)
: state(tab)
, sons(NULL)
{
}
请记住,必须在执行构造函数的主体之前完全初始化所有成员。因此 类 包含 类 的引用成员或实例,但没有定义 default/copy 构造函数,必须始终通过初始化列表初始化它们。
另外,如果你在Board
中定义了operator=()
,也定义复制构造函数(记住Rule of Three):
class Board
{
//...
Board(const Board&)
{
//make a copy
}
};
编辑
我觉得Board的拷贝构造函数应该这样实现:
Board(const Board& origin)
: tab(NULL)
, nbline(origin.nbline)
, nbcolumn(origin.nbcolumn)
, emptyspot(origin.emptyspot)
{
this->tab = new int*[this->nbline];
for (int i = 0; i < m; ++i)
this->tab[i] = new int[this->nbcolumn];
//Tab contains int's, so let's do simple memcpy()
memcpy(this->tab, origin.tab, sizeof(int) * this->nbline * this->nbcolumn);
}