0

Considering

class base { }

And

class derived: public base {}

What's the difference between:

FIRST CASE:

int main() {
  base b;
  derived d;
}

And

SECOND CASE:

int main() {
  base *b;
  derived *d;
}

And if we downcast and upcast in the second case like this:

  // upcast - implicit type cast allowed
  Base *b= &d; 

  // downcast - explicit type case required 
  Derived *d=  (Dervied *) &b;

How can we do it in the first case?

Amine
  • 1,396
  • 4
  • 15
  • 32
  • You don't need any `&` operators in the second case. You are already dealing with pointers. – François Andrieux Sep 19 '18 at 12:39
  • 1
    In the first case, assigning `d` to `b` will cause [object slicing](https://stackoverflow.com/questions/274626/what-is-object-slicing) and assigning from `b` to `d` doesn't make sense. – François Andrieux Sep 19 '18 at 12:40
  • Haven't used C++ since 2 years, trying to refresh my memory. If you can downcast and upcast in the second case, how can you do it in the first case? (Some friend told me we need to overload the = operator?) – Amine Sep 19 '18 at 12:43
  • You can't with value semantics (the first case). A `base` can never represent a `derived` (maybe for a limited number of cases of `base` designed specifically for it). Only a `base` *pointer* or *reference* can refer to a `derived`. – François Andrieux Sep 19 '18 at 12:44
  • So we need to make a copy constructor? – Amine Sep 19 '18 at 12:45
  • Sorry, I don't understand how your last comment relates to the questions. Could you please elaborate or rephrase? – François Andrieux Sep 19 '18 at 12:46
  • The way I understand, is what you said in your previous comment. You can only represent a derived class using a base class pointer or reference, that's why downcasting and upcasting are allowed when we declare the objects of the classes as pointers (I think we called them dynamic objects), – Amine Sep 19 '18 at 12:51
  • but since the first case aren't pointers (technically) (we called them static objects), we can't do any upcasting or downcasting, but in order to do so, we could use a copy constructor that creates a copy of the same object but with a pointer to that object, this way we can represent derived as a base. That's how I remember it, I might be mistaken – Amine Sep 19 '18 at 12:51
  • A friend also told me we can make the assignment by overloading the "=" operator, which I don't quite understand how yet. – Amine Sep 19 '18 at 12:52
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/180349/discussion-between-francois-andrieux-and-amine). – François Andrieux Sep 19 '18 at 12:52

1 Answers1

1

Parts of this answer is lifted from this stack overflow question.

Pointer and references allow for late binding/runtime polymorphism, while objects will cause object slicing (see @François Andrieux Comment).

What does this object slicing result in: If you use the objects directly you will lose information and maybe get the wrong methods called, even if you use virtual methods.

Here is an example:

#include <iostream>
using namespace std;

class A
   {
      public : virtual  void print(void)
           {
              cout<< "A::print()"<<endl;
           }
    };
 class B : public A
    {
      public : virtual void print(void)
           {
               cout<<"B::print()"<<endl;
           }
    };

int main(void)
{
    A a;
    B b;
    A& ref = b;

    a=b;
    a.print();
    ref.print();
    return 0;
}

Class B derives from A. A a = b; will lead to Class As print method being called, while using a reference (or pointer) would lead to Class Bs method being called (correct class is evaluated at runtime).

Your comments "how to make this" indicate to me that you are trying to solve a concrete problem. Could you state your exact problem instead of this? Making this work might not be the correct solution to your problem.

Concerning downcasting: As far as I know, you should only ever downcast if you have a base class pointer to a derived class object and you need to perform derived class methods on this and then the answer is dynamic_cast.

Ketzu
  • 660
  • 1
  • 7
  • 12
  • This problem is actually stated in an admission exam to a master's degree. The question says that considering **static** objects of base and derived, what can you say regarding the assignment d = b, with the possible answers being: 1. impossible, 2. can be done using a downcast d = (Derived) b, 3. can be done by overloading the = operator. – Amine Sep 19 '18 at 14:05
  • As you can overload the = operator, you can of course implement it as `Derived::Derived operator=(Base obj)` and have a statement `d = b` be valid and compile. `d = (Derived)b` should only compile if there exists a constructor `Derived::Derived(Base obj)`. Making the assignment `d=b` compile is by no means impossible. – Ketzu Sep 19 '18 at 14:27