joebuk
joebuk

Reputation: 11

C++ Derived Class override constructor value change

I cannot get 2 functions in the derived class to change values in the derived class as per the following code:-

#include <iostream>
#include <iomanip> // math related, e.g. setprecision(8);

using namespace std;

// class with setter functions
class BoxVol{   // a 'base' class, a class inheriting this one is a 'derived' class having an 'is a BoxVol' relationship.
    public: // private or protected 
        BoxVol(){   // constructor 1
            height=2.0; width=2.0; length=2.0;
        }   
        BoxVol(double w, double h, double l){   // constructor 2
            width1=w; height1=h; length1=l;
            cout << "From BoxVol constructor, width = " << width1 << endl;
        }
        void setWidth(double w){
         width = w;
        }
        void setHeight(double h){
         height = h;
        }
        void setLength(double l){
         length = l;
        }
// above, using default constructor, requires setters to set params
// Next uses a defined constructor where params are passed with the constructor declaration:

    protected:
    double width; double height; double length;
    double width1; double height1; double length1;

};

struct X{
  // ...
};

// another class with setter function
class BoxDensity{  // another base class

    public:     // default is private
        BoxDensity(){   // constructor 1
            density=1.0;
        }
        BoxDensity(double d){   //constructor 2
            density=d;
            cout << "From BoxDensity constructor, density = " << density << endl;
        }
        void setDensity(double d){
            density=d;
        }
    protected: double density;
};

// derived (inheriting) class with getter functions 
class BoxInfo: public BoxVol, public BoxDensity {    // multiple inheritance
    public:
        double getVol(){
            vol=width*height*length;
            return vol;
        }
        double getDensity(){
            d=getVol()*density;
            return d;
        }
        double getVol1(double w, double h, double l){
            BoxVol Box3Vol(w,h,l);
            cout << "From getVol1(w,h,l), width = " << width1 << endl;
            vol1=width1*height1*length1;
            return vol1;
        }
        double getDensity1(double d){
            BoxDensity Box3Density(d);
            cout << "From getDensity1(d), density = " << density << endl;
            d1=vol1*density;
            return d1;
        }
    protected:
        double vol,vol1,d,d1;
};

int main( ){
    BoxInfo Box1Specs, Box2Specs, Box3Specs;    // Declare 2 instances of BoxInfo
    double w=1.0,h=1.0,l=1.0,d=1.0;
    double volume=1.0, boxwt=1.0;
// private and protected members can not be accessed directly using direct member access operator (.)   
    Box1Specs.setHeight(5.0); Box1Specs.setLength(6.0); Box1Specs.setWidth(7.0);
    Box1Specs.setDensity(2.1);
    volume = Box1Specs.getVol(); boxwt=Box1Specs.getDensity();
    cout << endl;
    cout << "Volume of Box 1 : " << volume << " cubic cm; Weight of Box1: " << boxwt << " grams."<<endl;
    Box2Specs.setHeight(15.0); Box2Specs.setLength(16.0); Box2Specs.setWidth(17.0);
    volume = Box2Specs.getVol();
    cout << "Volume of Box 2 : " << volume <<endl;

    setprecision(8);
    cout << endl;
    cout << "For Box 3 enter values for: width height length, spaced -> ";
    cin >> w; cin >> h; cin >> l;
    cout << "width: " << w << ", height: " << h << ", length: " << l << endl;
    cout << endl;
    cout << "For Box 3, enter it's density -> "; cin >> d;
    cout << "Density: " << d << endl;
    cout << endl;
    volume=Box3Specs.getVol1(w,h,l); boxwt=Box3Specs.getDensity1(d);
    cout << endl;
    cout << "Volume of Box 3 : " << volume << " cubic cm." << endl;
    cout << "Weight of Box 3: " << boxwt << " grams." <<endl;

    return 0;
}

When I use the original variables (width, height, length, density), the values in the default constructor are used instead of those in the other. If I create new variables, as in adding 1 to the original names above, then what's returned is some double max or min value. Could someone please run this code to see the output for themselves and then see if he/she can spot the fallacy in it. Thank You.

Upvotes: 1

Views: 665

Answers (2)

evk1206
evk1206

Reputation: 453

Call Base class constructor in "member initialisation list" of derived class.

BoxInfo(double w, double h, double l,double d):BoxVol(w,h,l),BoxDensity(d)

With member initialisation list its possible to change the values to base class constructor. Remember that base class constructor is called first. Without member initialistion list, default constructor of base is called and you are not able to update the values.

Upvotes: 0

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153840

The short analysis of the program is this: it has undefined behavior. When you call Box3Specs.getVol1(w, h, l) an object which is default constructed is used. The default constructor only sets the members width, height, and length but it does not set width1, height1, or length1. The function getVol1() uses the latter three. Since these are uninitialized, the behavior is undefined.

getVol1() does construct an object Box3Vol which would be initialized correctly but is unused. You may have meant to use something along the lines of

*this = Box3Vol(w, h, l);

You should look up what member initializer lists are and I think you need to get rid of the duplicated set of members: they seem to cause confusion on what a BoxVol entity is. Since there is no description of what it meant to be, it is impossible to tell for sure, though.

Upvotes: 1

Related Questions