Плохая практика вызывать базовые методы в производных конструкторах? - PullRequest
2 голосов
/ 14 ноября 2011

Мне было просто интересно, каким наиболее эффективным способом установки унаследованных членов был и можно ли использовать следующий код:

Это объявление базового класса:

class cEntity{
private:
    int X, Y;
    int Height, Width;
public:
    cEntity();
    cEntity(int x,int y,int h,int w);
    ~cEntity();

    void setX(int x){X=x;};
    void setY(int y){Y=y;};
    void setCoords(int x, int y){X=x;Y=y;};

    void setHeight(int h){Height = h;};
    void setWidth(int w){Width = w;};
    void setArea(int h, int w){Height=h;Width=w;};

    int getX(){return X;};
    int getY(){return Y;};
    //void getXY(int,int);

    int getHeight(){return Height;};
    int getWidth(){return Width;};
    //void getArea(int,int);
};

и вот конструктор производного класса:

cOrganism::cOrganism () {
    setCoords(0,0);
    setArea(0,0);
    Name = "UNKNOWN";
    Health = 100;
    MaxHealth = 100;
    HealthHiRange =100;
    HealthLoRange = 100;
};

Итак. Можно ли вызывать setCoords() и setArea() в конструкторе производного класса?

Ответы [ 3 ]

7 голосов
/ 14 ноября 2011

Все хорошо, но вы можете добиться большего, вызвав базовый конструктор:

cOrganism::cOrganism() : cEntity(0, 0, 0, 0) {
  // other stuff
}

На самом деле, вы должны инициализировать своих новых, производных членов таким же образом:

cOrganism::cOrganism()
: cEntity(0, 0, 0, 0),
  Name("UNKNOWN"),
  Health(100),
  ...
{
}

(Возможно, вы также захотите немного прочесть об общем дизайне класса C ++: если вы предоставляете getter и setter для всех ваших приватных переменных, что-то не так. Класс должен инкапсулировать модель, в то время как вы делаете по существу обратное. Но это не техническая ошибка.)

1 голос
/ 14 ноября 2011

Гораздо лучше назвать это так:

cOrganism::cOrganism () : cEntity(0,0,0,0) {
  Name = "UNKNOWN";
  Health = 100;
  MaxHealth = 100;
  HealthHiRange =100;
  HealthLoRange = 100;
}

Или даже лучше:

cOrganism::cOrganism ()
 : cEntity(0,0,0,0), Name("UNKNOWN"), Health(100), 
   MaxHealth(100), HealthHiRange(100), HealthLoRange(100)
{}

Таким образом, члены базового класса устанавливаются при создании реализации базового класса.

0 голосов
/ 14 ноября 2011

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

В противном случае хорошим решением будет что-то вроде ниже.

class A
{
int x;
public:
    A( int xin) :x(xin) {}
};


class B : public A
{
int y;
public:
    B( int xin , int yin ) :A(xin) , y(yin) {}
};

Примечание A (xin) в конструкторе B. Это будет называться передачей xin конструктору A.

Если у вас есть что-то вроде целых чисел, это не имеет значения, что вы делаете. Но если A :: X был на самом деле тяжелым объектом. При вашем подходе A :: x будет создан один раз с конструктором по умолчанию, а затем назначен снова при вызове setCoords () из конструктора производного класса. Мое решение будет гарантировать, что A :: x * создается только один раз, и это тоже со всеми правильными значениями его параметров.

Подробнее здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...