简体   繁体   English

使用另一个类C ++构造一个类

[英]Constructing a class using an another class C++

I am new to C++ and recently took on the study of objective oriented programming. 我是C ++的新手,最近开始研究面向目标的编程。 I wanted to write my own linear algebra module processing three dimensional vectors and 3x3 matrices. 我想编写自己的线性代数模块来处理三维向量和3x3矩阵。 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. 如果有人能解释,我将非常感激。

You need to initialize your m1,m2,m3 members by member initializer list: 您需要按成员初始化列表初始化m1,m2,m3成员:

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. 您必须(至少在C ++之前的版本11中)使用此表单初始化非静态const数据成员。
  • 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. 另外,请注意,有std::vector ,您可能希望将自己的向量重命名为void命名冲突,并且最好通过const引用传递vector

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. 这里要认识到的重要一点是,在输入构造函数体之前,必须构造所有成员对象(在您的情况下为m1m2m3 )。

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 double s for construction, which it does not have. 问题是编译器不能自己构造vector成员:它只知道vector一个构造函数,并且它需要三个double s用于构造,它没有。 You can provide the compiler with those missing constructor arguments for vector using the initializer list syntax, as suggested by billz's answer. 您可以提供编译器与那些缺少构造函数参数为vector使用初始化列表语法,通过billz的答案的建议。

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. 或者,为vector提供默认构造函数,以便编译器能够自动构造矩阵成员而无需其他信息,如Zac的回答所示。

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

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. 您的vector类没有默认构造函数,因为您已经定义了一个带参数的显式构造函数。
  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. 因此,当编译器想要创建矩阵对象时,它需要首先构造/初始化m1 / m2 / m3,因为矩阵构造函数的这些代码“{m1 = a; m2 = b; m3 = c;}”。 However, the class of m1/m2/m3 has no default constructor to be called. 但是,m1 / m2 / m3的类没有要调用的默认构造函数。 This is why compiler reports "In constructor matrix::matrix(vector, vector, vector)': no matching function for call to vector::vector()'" 这就是编译器报告“在构造函数matrix::matrix(vector, vector, vector)': no matching function for call to vector :: vector()'“

The solution is to initialize the m1/m2/m3 through member initialization list. 解决方案是通过成员初始化列表初始化m1 / m2 / m3。 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. 可以通过成员初始化列表调用此“默认复制构造函数”。

Or with the "recommended c++11" way: 或者使用“推荐的c ++ 11”方式:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM