在派生构造函数中调用基方法是不好的做法

Bad practice to call base methods in derived constructors?

本文关键字:方法 构造函数 派生 调用      更新时间:2023-10-16

我只是想知道设置继承成员的最有效方法是什么,以及下面的代码是否可以使用:

这是基类的声明:

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() ?

这很好,但是您可以通过调用基构造函数来做得更好:

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

实际上,应该用同样的方法初始化新的派生成员:

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

(您可能还需要阅读一些通用c++类设计:如果您向所有私有变量公开getter和setter,则有些地方不太正确。一个类应该封装模型,而实际上您所做的恰恰相反。但这不是一个技术错误)

不如这样命名:

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)
{}

这样在构造基类实现时就可以设置基类成员。

如果基类的默认构造函数已经将其初始化为良好的值,则不必全部执行。

否则,好的解决方案如下:

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构造函数。这将把pass xin调用给A构造函数。

如果你有像整数这样的东西,你怎么做并不重要。但是如果A: X是一个很重的物体。使用您的方法,A::x将使用默认构造函数构造一次,然后在从派生类构造函数调用setcoordds()时再次赋值。我的解决方案将确保A::x*只构造一次,而且它的所有参数值都是正确的。

更多细节在这里