Search code examples
c++inheritanceradixderived

c++ inheritance : confused with base member access from derived object


Declaration:

class base{
public:
    base(){a=0;}
    base(int a);
    int getA();
    virtual ~base() ;
protected:
    int a ;
};
//
class derived : public base {
public:
    derived(){}
    derived(int a, int b) ;
    int getC() ;
    ~derived();
private:
    int c ;
};

Definition :

base::base(int a){
    cout << "   in base constructor a = " << a << endl ;
    a = a ;
}
base::~base(){
    a = 0 ;
}
int base::getA(){
    return a ;
}
//
derived::derived(int a, int b)
:base(a)
{
    c = a+b ;
}
int derived::getC()
{
    return c ;
}
derived::~derived(){
    c = 0 ;
}

Call:

derived A(4,5) ;
cout << "   a of A = " << A.getA() << "\n" ;
cout << "   c of A = " << A.getC() << "\n" ;

Result :

in base constructor a = 4
a of A = 4205648
c of A = 9

Please can someone explain why I am getting this result instead of :

a of A = 4 

? Why does the value of base member a change ? Based on what I've learned about inheritance in c++, when we create an object of derived class, this object will inherit all members and member functions of base class, why is it that the member a of object A of class derived loses its value outside the derived class definition ?

Thanks !


Solution

  • base::base(int a){
        cout << "   in base constructor a = " << a << endl ;
        a = a ;
    }
    

    This line changes the value of constructor parameter a, not the value of a of base. Better will be

    base::base(int _a){
        cout << "   in base constructor a = " << _a << endl ;
        a = _a ;
    }
    

    And even better is to use constructor initialization list:

    base::base(int _a): a(_a) {
        cout << "   in base constructor a = " << a << endl ;
    }
    

    In the latter case you can even write

    base::base(int a): a(a) {
        cout << "   in base constructor a = " << a << endl ;
    }
    

    because in the initialization list there is no ambiguity, although I still prefer to be explicit and use different names for constructor parameters and class members.