audio
audio

Reputation: 404

Constructing a class using an another class C++

I am new to C++ and recently took on the study of objective oriented programming. I wanted to write my own linear algebra module processing three dimensional vectors and 3x3 matrices. I tried to define a matrix as a class consisting of three vectors.

class vector {
  public:
  double n1, n2, n3;
  vector (double a, double b, double c) {
         n1 = a; n2 = b; n3 = c;
         }
  };

class matrix {
  public:
         vector m1, m2, m3;
         matrix (vector a, vector b, vector c) {
                m1 = a; m2 = b; m3 = c;
                }
         };

However, I am getting a compilation error:

In constructor `matrix::matrix(vector, vector, vector)':
no matching function for call to `vector::vector()'

I am guessing that the program doesnt know how to construct a matrix using the vector class i defined. However I do not understand why. If anybody could explain, i would be very grateful.

Upvotes: 5

Views: 564

Answers (5)

Fredrik Jansson
Fredrik Jansson

Reputation: 3814

Or with the "recommended c++11" way:

matrix (vector a, vector b, vector c)
: m1(std::move(a)),m2(std::move(b)),m3(std::move(c)) {
}

Upvotes: 0

JackyZhu
JackyZhu

Reputation: 404

The reason why you got this error is that:

  1. Your vector class has no default constructor as you have defined one explicit constructor with parameters.
  2. The data member of one object will be initialized during object construction but before the code in constructor is executed.

So when compiler wants to create matrix object, it needs to first construct/initialize m1/m2/m3 befor these codes "{ m1 = a; m2 = b; m3 = c;}" of matrix constructor. However, the class of m1/m2/m3 has no default constructor to be called. This is why compiler reports "In constructor matrix::matrix(vector, vector, vector)': no matching function for call tovector::vector()'"

The solution is to initialize the m1/m2/m3 through member initialization list. This works because:

  1. The compiler will provide "default copy constructor" (actually just bit-wise copy for your case) when it is not defined.
  2. This "default copy constructor" could be called through member initialization list.

Upvotes: 0

ComicSansMS
ComicSansMS

Reputation: 54737

Here's why this is going wrong:

Construction of an object happens in multiple phases. For your matrix class, you first need to construct all member objects and only then execute the constructor body. The important thing to realize here is that before the constructor body is entered, all member objects (in your case m1, m2 and m3) must have been constructed.

The problem is that the compiler cannot construct the vector members by itself: It only knows one constructor for vector and that one requires three doubles for construction, which it does not have. You can provide the compiler with those missing constructor arguments for vector using the initializer list syntax, as suggested by billz's answer.

This works because the initializer list is executed during the member-construction phase of startup, which happens before the constructor-body phase.

Alternatively, provide a default constructor for vector so that the compiler is able to automatically construct the matrix members without additional information, as suggested by Zac's answer.

Upvotes: 4

billz
billz

Reputation: 45450

You need to initialize your m1,m2,m3 members by member initializer list:

matrix (const vector& a, const vector& b, const vector& c)
: m1(a),m2(b),m3(c)

Note the following:

  • This form can be used only with constructors.
  • You must (at least, in pre-C++11) use this form to initialize a nonstatic const data member.
  • You must use this form to initialize a reference data member.

Also, note, there is std::vector, you may want to rename your own vector to void naming confliction and you'd better pass vector by const reference.

Upvotes: 6

Zac
Zac

Reputation: 4705

It is needed the default constructor of class vector, the one with no parameters:

class vector {
  public:
  double n1, n2, n3;
  vector () { // <- this one
    n1 = 0; n2 = -1; // sample initializing code
  };
  vector (double a, double b, double c) {
         n1 = a; n2 = b; n3 = c;
         }
  };

Upvotes: 1

Related Questions