0

Let's put it this way.....

struct A {virtual void something(){cout <<"I'm A.";}};
struct B, A 
{
void something(){cout << "I'm B.";}
void somethingFromB(){cout << "I'm from B.";}
}

int main()
{
A a = B();
//Now, here is where I want to call "somethingFromB" from A. How to?
}

So, as seen here, we have "something" that can be called from an object with type "A" just like an object with type "B". I now made an object with type "A" called a, and made it a "B". How to work with it just like it were a regular B object and be able to call "somethingFromB" from it?

EDIT--- I presume I could use:

A* a = new B(); ((B*)a)->somethingFromB();

Which seems to compile just fine :/

Helder Novais
  • 85
  • 4
  • 12
  • 2
    You need to read a very basic tutorial on C++ to learn the correct syntax when inheriting classes. And also read about [object slicing](https://en.wikipedia.org/wiki/Object_slicing), because the object `a` is not really an instance of the `B` class. – Some programmer dude Aug 01 '15 at 23:25
  • Can you explain what can I change here to call "somethingFromB"? – Helder Novais Aug 01 '15 at 23:26
  • @HelderNovais: You can't. `a` is not a B object, it's an A object. – MSalters Aug 01 '15 at 23:27
  • And when you fix the inheritance compiler problem, and the object slicing problem, then read about [`static_cast`](http://en.cppreference.com/w/cpp/language/static_cast) and [`dynamic_cast`](http://en.cppreference.com/w/cpp/language/dynamic_cast). – Some programmer dude Aug 01 '15 at 23:28
  • I know about static_cast. – Helder Novais Aug 01 '15 at 23:29
  • @MSalters , then what can I do from an A? – Helder Novais Aug 01 '15 at 23:30
  • 1
    Take a look at [object slicing](http://stackoverflow.com/q/274626/2069064). – Barry Aug 01 '15 at 23:31
  • 1
    You can only call `A::something()`. I agree with Joachim, you should get a book. – MSalters Aug 01 '15 at 23:32
  • @MSalters I don't understand how slicing could fix this. – Helder Novais Aug 02 '15 at 00:01
  • @HelderNovais you misunderstand. Slicing is not something that fixes your problem. Slicing is what happens in your current code and it is what makes calling `somethingFromB` impossible. Instance of `A` is an instance of `A`. It is not an instance of `B`. You cannot call member functions of class `B` on instances of `A`. For that you need an instance of `B`. – eerorika Aug 02 '15 at 00:05
  • Slicing will not fix this: its the root cause of your symptoms ! – Christophe Aug 02 '15 at 00:06

1 Answers1

1

The problem is that if you define an A object, it will remain an A object.

If you copy a derived object into it, there will be an implicit conversion performed. In fact, the A subobject inside B will be copied. This effect is known as slicing

You could also define your own constructor or assignment operator for making an A out of a B. But regardless the way you do control this copy, in the end, the targe object remains an A.

This is why A a = B(); will really create an A and behave as an A.

If you want to use the polymorphism and keep your type you can use a pointer or a reference:

A& ra = b;  // reference to an A object 
ra.something();  // ==> it's a B because ra refers to the original object

A* pa = &b;  // pointer to an A object
pa->something();  // ==> it's a B because pa points to the original object 

shared_ptr<B> spb = make_shared<B>();  // creates a shared pointer to a newly allocated B object
shared_ptr<A> spa = spb;  
spa->something();  // ==> it's a B again 

Attention: this polymorphic behaviour applies only to virtual functions of the base type (dynamic binding to the real object's member functions). For any non-virtual function pa and ra would use A's function. And you couldn't invoke B functions which are not defined for A.

Christophe
  • 68,716
  • 7
  • 72
  • 138