对参数的构造函数的未定义引用

undefined reference to constructor for argument

本文关键字:引用 未定义 构造函数 参数      更新时间:2023-10-16

晚上好

我对构造函数有一个小问题。我正试图建立一个我的董事会不同可能发挥的树(之后做DepthFirstSearch)。在我的节点类构造函数中,我想将当前板复制为树的叶子。但是,当我尝试使用Board类实例作为Node构造函数的参数时,我得到了一个错误"对`Board::Board'()'|的未定义引用"。

如果你知道如何正确地做到这一点,我在听,我真的没有看到任何问题:(

这是我的类节点:

class Node
{
private :
    Board      state;
    list<Node>  sons;
public :
                Node(Board&);
    void        addNode(Board&);
};

在进行Node构造函数时,我这样做:

Node::Node(Board& tab)
{
    state = tab;
    sons = NULL;
}

我的董事会课程是:

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;}}
}

这并不奇怪。在Node::Node(Board& tab)中,默认情况下,在进行分配之前对状态进行初始化。由于您并没有显式地执行此操作,所以编译器会调用未定义的Board::Board()。将Node::Node()更改为:

Node::Node(Board& tab)
: state(tab)
, sons(NULL)
{
}

记住,在执行构造函数的主体之前,必须完全初始化所有成员,这是必需的。因此,包含引用成员或类实例的类,若并没有定义默认/复制构造函数,则必须通过初始化列表对其进行初始化。

此外,如果您已经在Board中定义了operator=(),那么还可以定义复制构造函数(记住三条规则):

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);
}

由于state不在Node的构造函数初始化列表中,它将使用默认构造函数创建。问题是,Board没有默认的构造函数。要解决此问题,请使用初始化列表。这假设Board具有适当的复制构造函数。

Node::Node(const Board& tab)
    : state(tab)
{
}

我使参数常量。我还删除了列表分配。我不知道将NULL赋值给列表意味着什么,但如果它是std::list,那么它的默认构造函数无论如何都会将其创建为空。