简体   繁体   中英

Pass object to constructor of another class

I have two objects, data which is a large amount of data (duh) and node which I plan to use in a tree, where each node contains data. I want to create a node constructor where I pass it a data object but I am getting the following error:

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)

My constructors for data are:

 // "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 );

where the first one is such that I read the data from a file, the second two are methods for creating new data objects from previous data objects. The ability to pass data &data0 works fine in the data cosntructors, but when I try to create a node constructor:

 // "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);

I get the error. I know it is saying that I don't have a default constructor for data , but why do I need one? I am passing an object which has already been defined. Does data::data() , by default, allow for a copy or something that I'm not seeing? If so, why was I allowed to pass data &data0 to my data constructors without it barking at me?

EDIT:

Simply placing data::data(); into my data.h file and data::data() { } into my data.cpp file solves the problem, but I feel like there is something else going on - what am I missing about the way that objects get passed to constructors of other classes?

EDIT2: minimal code example.

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

I'm pretty sure the problem is that you don't put it in the initialiser-list. Showing your code for node might help. If you don't give your data member some value in the initialiser-list its default constructor will be called then you use the affectation operator to change its value which is probably what you don't want to do. If your class node contains a pointer instead of a reference it will be fine even if you don't initialise it because a pointer doesn't have to be initialised but a value or a reference has to (hence the call to the default constructor).

What happens to node_data when the node constructor starts running? What is it going to be set to? The compiler automatically attempts to call the default constructor.

This is another of an extremely long list of reasons why field initialization lists are ALWAYS best. If you set node_data to data0 in the field initialization list, it will attempt to call your copy constructor instead of the default constructor (which it looks like you also don't have).

If you don't want to define a copy constructor, then just stick with the solution you have right now and create a default constructor that does nothing.

Also, you're double including a couple times (this won't cause problems because the STL classes are protected from that, it's just pointless code). If you include something in the .h file, it is already automatically included in the .cpp file when you do #include "foo.h"

EDIT (field initialization list and copy constructor):

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

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