我有两个对象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 &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 &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 }
答案 0 :(得分:2)
我很确定问题是你没有把它放在初始化列表中。显示node
的代码可能有所帮助。
如果你没有在初始化列表中给你的数据成员一些值,那么将调用它的默认构造函数,然后使用effectation运算符来改变它的值,这可能是你不想做的。
如果你的类节点包含一个指针而不是一个引用,即使你没有初始化它也没关系,因为指针不必初始化但是必须有值或引用(因此调用默认的构造函数)
答案 1 :(得分:2)
节点构造函数开始运行时node_data
会发生什么?它将被设定为什么?编译器会自动尝试调用默认构造函数。
这是为什么字段初始化列表始终最佳的另一个非常长的原因列表。如果您在字段初始化列表中将node_data
设置为data0
,它将尝试调用您的复制构造函数而不是默认构造函数(它看起来您也没有)。
如果您不想定义复制构造函数,那么只需坚持使用现在的解决方案并创建一个不执行任何操作的默认构造函数。
此外,你要加倍,包括几次(这不会导致问题,因为STL类受到保护,它只是无意义的代码)。如果您在.h
文件中添加了某些内容,那么当您执行.cpp
时,它已自动包含在#include "foo.h"
文件中
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