简体   繁体   中英

Child's constructor doesn't recognize base class' members: mean, sigma “is not a nonstatic data member or base class”

The constructor in child class "RandomUniform" aims to reinitialize members "mean" and "sigma" of Mother class "RandomVar" if the object created becomes uniform. But I obtain the error: mean, sigma "is not a nonstatic data member or base class". As I understand, all members declared constructed in base class have to be redeclared and reconstructed (reinitialized) in child as static members (no difference with variables "uplimit" and "downlimit") and it is greatest idea of inheritance. So what is the problem?

Here is the best answer I have found: c++ Child class Unable to initialize Base class's member variable? but the sentence "this is because the base class (and by extension, all its data members) are initialized before the derived class and any of its members" is not clear for me. Is not constructor serves to reinitialize variable even if it was done before?

PS: I use notation RandomVar::RandomVar() as code below to show exactly how the methods are written in cpp file.

class RandomVar{

public:

double mean;
double sigma;

RandomVar();
virtual ~RandomVar();
};

RandomVar::RandomVar() : mean(0), sigma(1) {
}

RandomVar :: ~RandomVar(){
}

class RandUniform: public RandomVar  {
protected:
double downlimit;
double uplimit;
public:    
RandUniform();
virtual ~RandUniform();

};

RandUniform::RandUniform() : downlimit(0), uplimit(1), mean(0.5), sigma (sqrt(1/12)) {  
}

RandUniform :: ~RandUniform(){
}

You can only initialize objects once. After that you can only assign them:

RandUniform::RandUniform() : downlimit(0), uplimit(1) 
{
    mean = 0.5;
    sigma = sqrt(1./12);
}

Alternatively, you can delegate initialization of base class variables to base class constructor:

//Make it protected if you do not want end user to see it.
RandomVar::RandomVar(double m, double s) : mean(m), sigma(s) 
{}

RandUniform::RandUniform() : RandomVar(0.5, sqrt(1./12)), downlimit(0), uplimit(1) 
{}

the constructor for the parent object is called before RandUniform constructor. this is why the compiler is confused, the members you are setting are already declared(basically like writing int i; int i; ) . this is really comfortable when your parent class have a complicated initialization method.

any why's i don't know if it is considered best practice. but i usually have my parent object support a protected Set method. so i can do:

 RandUniform::RandUniform() : downlimit(0), uplimit(1){ 
      this->Set(0.5,sqrt(1/12));
 }

alternatively you can just do it manually:

  RandUniform::RandUniform() : downlimit(0), uplimit(1){ 
      mean = 0.5;
      sigma = sqrt(1/12);
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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