【问题标题】:Pass object to constructor of another class将对象传递给另一个类的构造函数
【发布时间】:2014-07-08 20:38:42
【问题描述】:

我有两个对象,data 是大量数据 (duh) 和 node,我计划在树中使用,其中每个节点都包含数据。我想创建一个 node 构造函数,并在其中传递一个 data 对象,但出现以下错误:

node.cpp: In constructor ‘node::node(data&, std::vector<int>)’: node.cpp:7:49: error: no matching function for call to ‘data::data()’ node::node(data &data0, vector<int> feature_list)

data 的构造函数是:

 // "data.h"
 13     // read the data from a file
 14     data(string fname);
 15
 16     // data set based on other data set
 17     data(data &data0, int iv_beg, int iv_end);
 18
 19     // data set based on other data set
 20     data(data &data0, vector< int > vectors );

第一个是我从文件中读取数据的地方,后两个是从以前的 data 对象创建新的 data 对象的方法。通过data &amp;data0 的能力在data cosntructors 中工作正常,但是当我尝试创建node 构造函数时:

 // "node.h"
 17     // create a node with the given data
 18     // --- tell it what features it is allowed to branch on
 19     node(data &data0, vector<int> feature_list);

我得到了错误。我知道这是说我没有data 的默认构造函数,但为什么我需要一个呢?我正在传递一个已经定义的对象。 data::data() 默认情况下是否允许复制或我看不到的东西?如果是这样,为什么我被允许将data &amp;data0 传递给我的data 构造函数而不会对我咆哮?

编辑:

只需将data::data(); 放入我的data.h 文件并将data::data() { } 放入我的data.cpp 文件即可解决问题,但我觉得还有其他事情发生 - 我错过了对象传递的方式其他类的构造函数?

EDIT2:最小代码示例。

  "node.h":
  1 #ifndef _NODE_H_
  2 #define _NODE_H_
  3
  4 #include "data.h"
  5 #include <vector>
  6 #include <string>
  7
  8 class node {
  9   public:
 10     node(data &data0, vector<int> feature_list);
 11   private:
 12     data node_data; // data for this node
 13 };
 14 #endif

  "node.cpp"
  1 #include "node.h"
  2 #include "data.h"
  3 #include <vector>
  4
  5 node::node(data &data0, vector<int> feature_list) {
  6   data0.print();
  7 }

  "data.h"
  1 #ifndef _DATA_H_
  2 #define _DATA_H_
  3
  4 #include <string>
  5 #include <vector>
  6
  7 using namespace std;
  8
  9 /////// object to hold data
 10 class data {
 11
 12   public:
 13     // data set based on file
 14     data(string fname);
 15     // print the dat set
 16     void print();
 17     int nvectors();
 18     int nfeatures();
 19     vector< string > feature_names();
 20     vector< double > feature_vector(int iv);
 21
 22   private:
 23     void read_datfile();
 24     string _fname;
 25     vector< string > _features;
 26     vector<vector< double > > _x;
 27     int _Nf; // number of features
 28     int _Nv; // number of feature vectors
 29 };
 30
 31 #endif



  "data.cpp"
  1 #include "data.h"
  2
  3 #include <string>
  4 #include <string.h>
  5 #include <vector>
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include <fstream>
  9 #include <iostream>
 10
 11 using namespace std;
 12
 13 // data set which is derived fom a file
 14 data::data(string fname) {
 15   _fname = fname;
 16   read_datfile();
 17 }
 18
 19 // print the vectors in the data set
 20 void data::print() {
 21   int iv_beg = 0;
 22   int iv_end = 2;
 23
 24   vector<double> tvect[_Nf];
 25   if(iv_end < _Nv) {
 26     for(int iv = iv_beg; iv<iv_end; iv++) {
 27       printf("VECTOR %i\n", iv);
 28       for(int ifeat = 0; ifeat<_Nf; ifeat++) {
 29         printf("%25s ... %f\n", _features[ifeat].c_str(), _x[iv][ifeat]);
 30       }
 31     }
 32   }
 33   else {
 34     printf("ERROR: there are not that many vectors in this data set\n");
 35   }
 36 }
 37
 38 // read the file
 39 void data::read_datfile() {
 ...
 87 }

【问题讨论】:

  • 我对你的问题有点困惑。重点是data 没有在node 内部构造,data 对象只是被传递。它已经构建并拥有所需的所有信息。
  • 您向我们展示的代码很好。您未向我们显示的代码有错误。见How to create a Minimal, Complete, and Verifiable example
  • 谢谢,我应该关闭这个并打开一个显示所有代码相关代码的新问题还是只更新这个?

标签: c++ object constructor


【解决方案1】:

当节点构造函数开始运行时,node_data 会发生什么?它将被设置为什么?编译器会自动尝试调用默认构造函数。

这是字段初始化列表总是最好的原因的另一个非常长的列表。如果您在字段初始化列表中将node_data 设置为data0,它将尝试调用您的复制构造函数而不是默认构造函数(看起来您也没有)。

如果您不想定义复制构造函数,那么只需坚持您现在拥有的解决方案并创建一个什么都不做的默认构造函数。

另外,你是双重的,包括几次(这不会引起问题,因为 STL 类受到保护,它只是无意义的代码)。如果您在.h 文件中包含某些内容,那么当您执行#include "foo.h" 时,它已经自动包含在.cpp 文件中

EDIT(字段初始化列表和复制构造函数):

class data {
    public:
        data(const data &that) { //Create the copy constructor
            //Simply copy over all of the values
            _fname = that._fname;
            _features = that._features;
            _x = that._x;
            _Nf = that._Nf;
            _Nv = that._Nv;
        }

        ...
}

node::node(data &data0, vector<int> feature_list) 
    : node_data(data0) { } //Initialize node_data in the initialization list

【讨论】:

  • 谢谢,我创建了一个什么都不做的默认构造函数,它解决了这个问题。如果它调用默认构造函数,那么为什么在进入node 构造函数时会产生正确的data 节点成员?为data创建默认(空)构造函数后,它正确打印出传递的data对象的内容,但是如果调用默认构造函数,data中的信息将是空的,对吧?
  • @Laurbert515 小心。我不知道你的数据成员叫什么,但请给我们它的名字并用它重新表述你的评论,这样就不会变得更加混乱。我不明白then why is the correct data node member resulting upon entering the node constructor?
  • 谢谢,我正在尝试将一个名为 data0data 对象传递给我的 node。如果我放置一个空白的data::data() 构造函数,它实际上什么都不做,为什么在将data0 传递给我的node 构造函数时,我能够在data0 中打印data0 的内容node构造函数?
  • @Laurbert515 在data0 上没有调用默认构造函数。 data0 已经是数据类的完整实例。 “数据节点成员变量”是指node_data。那是调用默认构造函数的数据实例。
  • @Laurbert515 我已经编辑了我的答案,试图让事情更清楚^
【解决方案2】:

我很确定问题是你没有把它放在初始化列表中。显示node 的代码可能会有所帮助。 如果你没有在初始化列表中给你的数据成员一些值,它的默认构造函数将被调用,那么你使用影响运算符来改变它的值,这可能是你不想做的。 如果您的类节点包含指针而不是引用,即使您不初始化它也可以,因为不必初始化指针,但必须初始化值或引用(因此调用默认构造函数) .

【讨论】:

    猜你喜欢
    • 2017-03-07
    • 2019-03-09
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    相关资源
    最近更新 更多