Невозможно объединить список инициализаторов с наследованием - PullRequest
0 голосов
/ 26 сентября 2019

У меня есть некоторый код, в котором я хотел бы, чтобы экземпляр класса мог инициализировать переменную в своем инициализаторе, а также вызывать в своем списке инициализатора конструктор родительского класса.Этот конструктор родительского класса будет инициализировать три дополнительные переменные в списке инициализатора своего собственного конструктора.

Вот некоторый код, который использует этот конструктор в другом классе:

class Vec3f {
public:
  inline Vec3f () : x (0), y (0), z (0) {}
  inline Vec3f (float xx, float yy, float zz) : x (xx), y (yy), z (zz)  { }
private:
  float x,y,z;
};

class Vec4f : Vec3f {
   public:
      inline Vec4f (): Vec3f(), w(0) {}
      inline Vec4f (float a,float b,float c,float d): Vec3f (a,b,c), w(d) {}
private:
    float w;
};

class Matrix4x4 {
   public:
      void setIdentity ();
    private:
      Vec4f row1, row2, row3, row4;
};

void Matrix4x4::setIdentity () {
  row1 (1.0f,0.0f,0.0f,0.0f);
  row2 (0.0f,1.0f,0.0f,0.0f);
  row3 (0.0f,0.0f,1.0f,0.0f);
  row4 (0.0f,0.0f,0.0f,1.0f);
}


main () {
   Matrix4x4 a;
   a.setIdentity ();
}

Когда я запускаю приведенный выше код,Я получаю:

test.cpp: In member function ‘void    Matrix4x4::setIdentity()’:
test.cpp:26: error: no match for call to ‘(Vec4f) (float, float, float, float)’
test.cpp:27: error: no match for call to ‘(Vec4f) (float, float, float, float)’
test.cpp:28: error: no match for call to ‘(Vec4f) (float, float, float, float)’
test.cpp:29: error: no match for call to ‘(Vec4f) (float, float, float, float)’

На другой доске объявлений кто-то предложил это:

class Vec3f {
public:
  inline Vec3f () : x (0), y (0), z (0) {}
  inline Vec3f (float xx, float yy, float zz) : x (xx), y (yy), z (zz)  { }
  inline void Set3f (float xx, float yy, float zz) {
    x = (xx);
    y = (yy);
    z = (zz);
  }
private:
  float x,y,z;
};

class Vec4f : Vec3f
{
   public:
     inline Vec4f (): Vec3f(), w(0) {}
     inline Vec4f (float a,float b,float c,float d): Vec3f (a,b,c), w(d) {}
     inline void Set4f (float a,float b,float c,float d) {
     Set3f(a,b,c);
     w = d;
     }
   private:
     float w;
};

class Matrix4x4 {
  public:
    void setIdentity ();
    Matrix4x4() :
      row1 (1.0f,0.0f,0.0f,0.0f),
      row2 (0.0f,1.0f,0.0f,0.0f),
      row3 (0.0f,0.0f,1.0f,0.0f),
      row4 (0.0f,0.0f,0.0f,1.0f)
   {}
  private:
     Vec4f row1, row2, row3, row4;
};

void Matrix4x4::setIdentity () {
  row1.Set4f(1.0f,0.0f,0.0f,0.0f);
  row2.Set4f(0.0f,1.0f,0.0f,0.0f);
  row3.Set4f(0.0f,0.0f,1.0f,0.0f);
  row4.Set4f(0.0f,0.0f,0.0f,1.0f);
}


int main () {
  Matrix4x4 a;
  a.setIdentity ();
}

Однако это кажется мне взломом.Не хочу вызывать два метода сеттера.Лучше просто делать то, что мне нужно, в обычном конструкторе, меньше кода.Поэтому я спрашиваю: почему c ++ не позволяет списку инициализатора конструктора работать так, как я хочу?

1 Ответ

2 голосов
/ 26 сентября 2019

Вы не используете список инициализатора конструктора в setIdentity(), поэтому ваш код дает сбой.

Vec4f не реализует operator() (оператор вызова функции ), поэтому утверждения типа

row1 (1.0f,0.0f,0.0f,0.0f);

внутри setIdentity() не работают, и, кроме того, они не делают того, о чем вы думаете, они все равно делают.

Вы, вероятно, намеревались создать новые Vec4f экземпляры и назначить их существующим переменным, например:

void Matrix4x4::setIdentity () {
  row1 = Vec4f(1.0f,0.0f,0.0f,0.0f);
  row2 = Vec4f(0.0f,1.0f,0.0f,0.0f);
  row3 = Vec4f(0.0f,0.0f,1.0f,0.0f);
  row4 = Vec4f(0.0f,0.0f,0.0f,1.0f);
}
...