0

considere a simle class stDeriv which inherits from stBase. I'am surprised to see that we cannot access to the stDeriv class members through a stBase reference.

Below the basic example to illustrate my point :

#include <fstream> // std::ifstream #include <iostream> // std::cout using namespace std; typedef struct stBase { public: virtual ~stBase() { ; } stBase(int iB) { iB_ = iB; } // Copy operator stBase &operator=(const stBase &src) { iB_ = src.iB_; return *this; } virtual void Hello() { cout << " Hello from stBase" << endl; } private: int iB_ = 0; } stBase; typedef struct stDeriv : public stBase { public: int iD_ = 0; stDeriv(int iB) : stBase(iB), iD_(0) { ; } virtual void Hello() { cout << " Hello from stDeriv" << endl; } // Copy operator stDeriv &operator=(const stDeriv &src) { iD_ = src.iD_; return *this; } } stDeriv; int main(int, char *[]) { int iErr = 0; stBase aBase(0); stDeriv aDeriv(1); stDeriv &rDeriv = aDeriv; stBase &rBase = aBase; rBase.Hello(); // OK result : "Hello from stBase" rDeriv.Hello(); // OK result : "Hello from stDeriv" rBase = rDeriv; // KO!!! Cannot access to aDeriv.iD_ through rBase !!! rBase.Hello(); // KO!!! result : "Hello from stBase" !!! return iErr; } 

Why do I fail to access to stDeriv::iD_ through rBase after "rBase = rDeriv;" ?

5
  • A Deriv is a Base, but a Base is not a Deriv. This is the reason. Commented Oct 18, 2021 at 11:00
  • The typedef struct A {} A; construct is a C-ism that, while formally valid, has no use in C++. Commented Oct 18, 2021 at 11:49
  • rBase is a reference to stBase. Look at the definition of the stBase struct. Does it have an iD_ member? No, it doesn't, and that's why you can't access it. Commented Oct 18, 2021 at 11:52
  • 1
    rBase = rDeriv; does not change the reference, but the referred-to object: in your code it's equivalent to aBase = aDeriv;. Commented Oct 18, 2021 at 12:09
  • After the line "rBase = rDeriv;", I expected to be able to visit aDeriv attributes, which is unfortunately wrong. All is clearly explained in the Pepijn Kramer' s answer below. Commented Oct 18, 2021 at 14:30

1 Answer 1

1

You cannot rebind references like you do. rBase already has a value and cannot be assigned to again. why doesn't C++ allow rebinding a reference?

So just make a new reference:

int main(int, char* []) { int iErr = 0; stBase aBase(0); stDeriv aDeriv(1); stDeriv& rDeriv = aDeriv; stBase& rBase = aBase; rBase.Hello(); // OK result : "Hello from stBase" rDeriv.Hello(); // OK result : "Hello from stDeriv" // Make a new reference and all is fine stBase& rBase2 = rDeriv; rBase2.Hello(); // OK result : "Hello from stDeriv" return iErr; } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.