Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing fields of derived class object, C++ vs Java

If one accesses the fields of derived class object after assignment this object to variable of base class type in java, i get the expected behaviour, meaning print field's value of the derived class . In c++ value of the field, belonging to the base class is printed.

In Java, 6 is printed as expected:

class Ideone
{

    static class A {
        static int a = 7;
    }
    static class B extends A {
        static int b = 6;
    }
    public static void main (String[] args) throws java.lang.Exception
    {

        A a = new B();
        System.out.println(((B)a).b);
    }
}

In C++, 7 is printed:

#include <iostream>
using namespace std;

class Base {
    int i = 7;
public:

    Base(){
        std::cout << "Constructor base" << std::endl;
    }
    ~Base(){
        std::cout << "Destructor base" << std::endl;
    }
    Base& operator=(const Base& a){
        std::cout << "Assignment base" << std::endl;
    }
};

class Derived : public Base{
public:
    int j = 6;
};

int main ( int argc, char **argv ) {
    Base b;
    Derived p;
    cout << p.j << endl;
    b = p;
    Derived pcasted = static_cast<Derived&>(b);
    cout << pcasted.j << endl;
    return 0;
}

Is it possible to achieve in c++ similar type of behaviour (printing 6).

like image 854
rok Avatar asked Dec 18 '22 16:12

rok


2 Answers

Is it possible to achieve in c++ similar type of behaviour (printing 6).

It sure is, as long as you do the same thing as you do in Java.

You must remember, that even though Java has similar syntax, it is not identical. In Java, the statement A a = new B(); creates a reference of base type, bound to a derived type. ((B)a) then casts the type of the reference down to derived.

In c++, Base b; is not a reference variable. Copy-assigning a derived object to this variable will copy the base-sub-object of the derived object. This language feature is known as slicing. Simply use a reference to have similar semantics to your Java code:

Base& b = p;

If you access an object of concrete type Base, through a Derived& reference, you invoke undefined behaviour.

P.S. your assignment operator does not return anything, despite the return type being non-void. Not returning has undefined behaviour.

like image 144
eerorika Avatar answered Dec 21 '22 05:12

eerorika


In the C++ code, b = p; just slicing copied p to b, b is still Base in fact. Then static_cast<Derived&>(b) will fail and lead to UB.

You could use reference or pointer, letting b point to Derived in fact. Then it'll be fine to down-cast it to Derived.

int main ( int argc, char **argv ) {

    Derived p;
    Base& b = p;
    cout << static_cast<Derived&>(b).j << endl;
    return 0;
}

LIVE

like image 34
songyuanyao Avatar answered Dec 21 '22 06:12

songyuanyao