简体   繁体   中英

undefined reference to constructor for argument

Good evening

I have a small problem with a constructor. I'm trying to build a tree of the different possible plays of my board (to do a DepthFirstSearch after). In my node class constructor, i want to copy the current board as a leaf for the tree. But i got an error "undefined reference to `Board::Board()'|" when i try to use my Board class instance as an argument for Node constructor.

If you have an idea of how to do this correctly, i'm listening, i really don't see any problem :(

Here is my class node :

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

While doing the Node constructor, i do this :

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

My Board class is :

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

EDIT : Due to people asking, here are the constructors of 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;}}
}

As state is not in Node 's constructor initialization list, it will be created with its default constructor. The problem is, Board has no default constructor. To fix the problem, use the initialization list. This assumes that Board has an appropriate copy constructor.

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

I made the parameter const. I also removed the list assignment. I don't know what it means to assign NULL to a list, but if it's std::list then its default constructor will create it empty anyway.

It is not strange. In Node::Node(Board& tab) state is default-initialized before you make an assignment. Since you doesn't do it explicitly, compiler calls Board::Board() , which is not defined. Change Node::Node() to:

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

Remember, it is required, that all members must be fully-initialized before body of the constructor gets executed. So classes containing reference members or instances of classes, that do not have default/copy constructor defined, always must initialize them via initialization list.

Also, if you have defined operator=() in Board , define also copy constructor (rememeber about Rule of Three ):

class Board
{
//...

  Board(const Board&)
  {
    //make a copy
  }

};

EDIT

I think Board's copy constructor should be implemented this way:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM