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

C++ 参数对构造函数的未定义引用,c++,constructor,undefined-reference,C++,Constructor,Undefined Reference,晚上好 我对构造函数有一个小问题。我试图建立一个不同的可能发挥我的董事会树(做一个深度优先搜索后)。在我的节点类构造函数中,我想将当前板复制为树的叶子。但是,当我尝试使用我的Board类实例作为节点构造函数的参数时,出现了一个错误“未定义对`Board::Board()'|的引用” 如果您知道如何正确执行此操作,我在听,我真的没有发现任何问题:( 这是我的类节点: class Node { private : Board state; list<Node>

晚上好

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

如果您知道如何正确执行此操作,我在听,我真的没有发现任何问题:(

这是我的类节点:

class Node
{
private :
    Board      state;
    list<Node>  sons;
public :
                Node(Board&);
    void        addNode(Board&);
};
我的董事会课程是:

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(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;}}
}
Board::Board(intm,intn,Play&jeu):tab{newint*[m]},nbline{m},nbcolumn{n},emptyspot{n-1,m-1}{
int x(1);
对于(int i=0;i
由于
状态
不在
节点
的构造函数初始化列表中,它将使用其默认构造函数创建。问题是,
没有默认构造函数。若要解决此问题,请使用初始化列表。这假设
具有适当的副本构造函数

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)
{
}
请记住,在执行构造函数体之前,必须完全初始化所有成员。因此,包含引用成员或类实例的类(未定义默认/复制构造函数)必须始终通过初始化列表初始化它们

此外,如果您已在
线路板
中定义了
运算符=()
,请同时定义复制构造函数(请记住):

编辑

我认为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);
}
线路板(线路板和原点)
:制表符(空)
,nbline(origin.nbline)
,nbcolumn(origin.nbcolumn)
,emptyspot(origin.emptyspot)
{
此->选项卡=新整数*[此->nbline];
对于(int i=0;itab[i]=newint[this->nbcolumn];
//Tab包含int,所以让我们做一个简单的memcpy()
memcpy(this->tab,origin.tab,sizeof(int)*this->nbline*this->nbcolumn);
}

奇怪的是,你有一个赋值运算符,但没有复制构造函数。你是在为
Board
定义构造函数吗?你刚刚列出了声明。你的意思是我应该在Board中有一个构造函数将Board的现有实例复制到一个新实例上吗?:o:o如何?理想情况下,你应该设计你的类,使其默认值为-g生成的复制构造函数和赋值运算符将起作用。我不知道情况是否如此,因为我不知道您的构造函数在做什么。希望其中没有新的
new
。您需要一个正常工作的复制构造函数,我的解决方案才能起作用。不要使用新闻和指针!使用
std::vector matrix(ysize,std::vector(xsize))
可以用作矩阵[y][x]
。这样你的类就不会泄漏内存,也不需要提供复制构造函数或赋值运算符。它就可以工作了。没错,它现在正在编译:o std::list默认构造为空?太好了,你能帮我创建复制构造函数吗?\u.这样可以吗?Board::Board(const Board&other):tab(other.tab),nbline(other.nbline)、nbcolumn(other.nbcolumn)、emptyspot(other.emptyspot){}@Csi相信我。学习向量,然后不必创建复制构造函数,比调试和使用自定义构造函数更容易。这是正确的复制构造函数吗?还是我错了?Board::Board(const Board&other):tab(other.tab)、nbline(other.nbline)、nbcolumn(other.nbcolumn),emptyspot(other.emptyspot){}不,你不能通过简单的赋值复制tab,因为你会多次释放相同的资源。我会用正确的实现更新我的答案。为什么它会多次释放相同的资源?用正确的实现更新会对我有很大帮助。我几乎没听说过复制构造函数,所以我有点迷茫:(在您的更新帮助下,我将能够为我的其他类创建我自己的副本构造函数,看看我是否理解得很好。非常感谢。如果我理解得很好,我的类position也应该有一个副本构造函数,因为emptyspot是position的一个实例,并在Board copy构造函数中使用,对吗?
选项卡
是一个指针。您可以使用
new
为其内容添加内存,并使用
delete
在析构函数中释放它(你是这样做的,不是吗?)。如果你只是简单地使用
tab(origin.tab)
,您将有两个
选项卡
指向相同的内存位置。在销毁第一个对象后,第二个对象将使用已释放的内存,然后再次尝试释放它。
class Board
{
//...

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

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