user3191398
user3191398

Reputation:

How to get subclass member in c++

For example I have two class

class A:

class A
{
   private:
   int a;

}

subclass B:

class B: private A
{
   private:
   char b;

   public:
   char getB();
}

code:

int main()
{
   A* item = new B();
   char b = (B)item->getB();
}

Should I use cast or should I redesign program if I need to do something like that? I dont want to use polymorphism.

Upvotes: 2

Views: 2125

Answers (2)

Elohim Meth
Elohim Meth

Reputation: 1827

You should use dynamic_cast that safely converts pointers and references to classes up, down, and sideways along the inheritance hierarchy (cppreference.com):

dynamic_cast<B*>(item)->getB();

, instead of old style C cast:

((B*)item)->getB();

Edit:

You should use public inheritance to use dynamic_cast. For what purpose private inheritance was used? In your example it doesn't make much sense IMHO. Also using inheritance without virtual destructor is dangerous.

Upvotes: 1

Christophe
Christophe

Reputation: 73376

The problems

1) B privately inherits from A. So only a B can cast a B* to an A*.

2) The priorities of your expression are same as (B)(item->getB()); So this will not compile as item is an A and A has no member getB().

3) It's better to use static_cast or dynamic_cast instead of the old C style cast.

The solution

1) Use public inheritance if you want to cast between your derived class and base class outside of the classes themselves.

2) Then use parenthesis:

char b = ((B*)item)->getB();

3) Or prefer more precise form:

char b = static_cast<B*>(item)->getB();

4) But when you're doing an downcast like this, it's at your own risk. If the A* pointer points to something else than a B or a class derived from B, then it's undefined behaviour.

As you consider having a polymorphic use of your type, you'd better have a virtual destructor so that you can delete item with the appropriate destructor (here it would use A's destructor instead of B's).

As soon as you've at least one virtual function, you can use the safer dynamic_cast:

 if(dynamic_cast<B*>(item)) {  // would be nullptr if item doesn't point to a B object
     char b = dynamic_cast<B*>(item)->getB();
     ... // further processing of the char
  }
  else cout << "Ooops!"<<endl; 

Upvotes: 3

Related Questions