How to create objects outside functions with polymorphism?


Keywords:c++ 


Question: 

I want to use polymorphism and create objects outside of main or any other function so that the functions are independent of the type of the objects I have. My code is as follows:

The main class:

class load{   //Main class
protected:
    static load **L;
    static int n, n1;
public:
    load(){};
    virtual float getpower()=0;
    static int getn();
    static load ** getL();
};

load **load::L;
int load::n; 
int load::n1;

int load::getn(){
    return n;
}

load** load::getL(){
    return L;
}

The child class:

class load1:public load{ 
private:
    float power;
public:
    load1();
    load1(int s);
    void createUnits1();
    float getpower();
}l1(0);               //Object creation

load1::load1(int s){
    createUnits1();
}

void load1::createUnits1(){
    cout<<"Give the number of type 1 objects: "<<endl;
    cin>>n1;
    for (int i=0;i<n1;i++){
        load1 temp;         //Run default constructor
    }
}

load1::load1(){
    cout<<"Give the power of the device: "<<endl;
    cin>>power;
    n++;
    if (n==1){
        L=(load **)malloc(n*sizeof(load *));
    }
    else {
        L=(load **)realloc(L,n*sizeof(load *));
    }
    L[n-1]=this;
}

float load1::getpower(){
    return power;
}

The function of calculation:

float get_total_P(load **l, int num){
    float tot_power=0;
    for(int i=0;i<num;i++){
        tot_power+=l[i]->getpower();
    }
    return tot_power;
}

My main function:

int main() {
    load **l;
    int num;
    num=load::getn();
    l=load::getL();
    float total_P=get_total_P(l, num);
    cout<<total_P;
    return 0;
}

The upper code produces a segmentation fault but I can't see the reason why. The segmentation fault is on the line

tot_power+=l[i]->getpower();

So I guess my way of creating objects is wrong. Is there a better way to do this?


1 Answer: 

The reason for your segfault, is that l doesn't point to anything valid !

In main() you initialise l with load::getL(). But this function only returns the load::L which has the same type and was defined as static in your load class but was never initialized.

You have coded in your derived class load1 some initialisation code for L, but it is never invoqued in main().

Your code has also some severe design issues:

  • It's not advised to use malloc() and realloc() in C++ code. If you create an object in C++ use new. If you want some dynamic array, use vectors.

  • You could get L and hence l initialized if you'd create some load1 objects before calling getL(). But due to your realloc, l would then risk to point to an obsolete thus invalid address, if you would create any other load1 object before calling get_total().

  • It's bad practice and terrible design to request user input in a constructor. The constructor is meant to cosntruct an object with the parameters you give him when you call him. Imagine the user would give an invalid parameter ? The user would be asked for input whenever a load1 object is constucted. Even for temporary variables, not even speaking from the effect when you'd write load1 a[10];