0
#include <iostream>
using std::cout;
using std::endl;
class Base
{
public :
    void f();
    void g();

    int mBaseData1;

};

class Derived : public Base
{
public : 


    int mDerivedData1;
};

void main()
{

    Base* base = new Base();
    Derived* derived = (Derived*)(base); // DownCast
    derived->mDerivedData1 = 6;
    cout<< derived->mDerivedData1<<endl; // Result = 6;
}

in this code new base() allocate memory in heap

and Derived* derived = (Derived*)(base) cast base to derived

how we can use mDerivedData1? i cant find where we allocate memory for mDerivedData1 or when we call constructor of Derived for allocate mDerivedData1 ?

Randolpho
  • 55,384
  • 17
  • 145
  • 179
maysam
  • 509
  • 10
  • 23

5 Answers5

7

The reason you can't find where memory for mDerivedData1 was allocated is because no memory was allocated. You have performed an invalid type-cast. The thing stored in base is a pointer to a Base instance. Using a type-cast to tell the compiler that it's actually a pointer to a Derived instance doesn't make it so (but the compiler will believe you anyway because you're the one in charge). The object is still just a Base. If you want a Derived, then you'll need to instantiate a Derived. You can use dynamic_cast to convert the Base pointer into a Derived pointer.

Base* base = new Derived;
Derived* derived = dynamic_cast<Derived*>(base);
derived->mDerivedData1 = 6;
Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
4

It will work correctly if you change:

Base* base = new Base();

to:

Base* base = new Derived();

but in general you should never downcast unless you are really sure you know what you are doing, and even then it's usually a sign of a very bad design.

Mr Fooz
  • 109,094
  • 6
  • 73
  • 101
Paul R
  • 208,748
  • 37
  • 389
  • 560
2

You are really overwritting some part of the heap that is not part of the original base object. This could overwrite another object on the heap, or other unexplained happenings could occur.

C++ lets you do what you tell it to do for the most part. You are shooting yourself in the foot. :)

Starkey
  • 9,673
  • 6
  • 31
  • 51
2

Your program exhibits undefined behavior. You cannot access mDerivedData1 because you don't actually have an instance of Derived.

imaginaryboy
  • 5,979
  • 1
  • 32
  • 27
1

You can cast an instance of a child class to a base class, but you cannot (well... should not) cast an instance of a base class into a child class.

Edit:

If you are confused about how casting works:

An object never actually changes during a cast -- in truth an object is really just a contiguous block of memory. When an object is cast, the only thing that changes is how the program sees and works with the object.

That's why casting an instance of a base object to a child object results in undefined behavior; the runtime interprets the base object as a child object and uses the pointer for the object as a starting point for referencing data of the object. If a field that is defined on the child class is used on a base object cast as the child object, the program will reference memory that is not part of the instance. If this referenced memory happens to be unused by the rest of the program, things might seem just fine (for a little while), but if the memory is used by another object, strange things could happen in your program -- the other object might have a value changed that it shouldn't have, or worse. And this is just when dealing with heap allocated objects; try this with a pointer to a stack allocated object and you could totally derail your entire program -- assuming you don't segfault.

So in general, if B derives from A:

  1. You can cast an instance of B to A
  2. You can cast an instance of B that is already cast as an A back to B, but this may indicate sloppy architecture of your program.
  3. You cannot (should not) cast an instance of A to B, as this will result in undefined behavior.
Randolpho
  • 55,384
  • 17
  • 145
  • 179
  • That's a tad misleading... If you cast an instance of Derived to Base, that will cause slicing. Presumably you mean you can cast a Derived* to a Base* -- which is true, but provided Base is polymorphic, the cast isn't required. Going the other way, there can be occasions when downcasting is expedient, but as a general rule (i.e. not always) it tends to be indicative of a dubious design. – Stuart Golodetz Nov 15 '10 at 20:43
  • @sgolodetz: I never said you can't downcast; neither scenario I mentioned is a downcast. Downcasting is casting an instance of a child class that is currently cast as a base class back to the child class. You should not cast an instance of a base class -- not a child class cast as a base class, but an instance of the *base* class -- to a child class. I say should not rather than cannot, because C++ will let you cast however you like all day long (depending on the cast you use), but if you try to use the base as a child, you'll get undefined behavior. If you're lucky, you'll get a segfault. – Randolpho Nov 15 '10 at 21:04
  • @Randolpho: I think I misread your post, sorry. To clarify: (a) you can cast an instance of Derived to Base, which slices it; (b) you shouldn't cast an instance of Base to Derived, because that causes undefined behaviour; (c) you don't need to cast a Derived* to a Base* because there's an implicit conversion; (d) you can cast a Base* to a Derived*, but it's often indicative of bad design. With (d), if you use dynamic_cast, you'll get NULL if your Base* doesn't actually point to an instance of Derived. Sorry for missing the point of what you were saying :) – Stuart Golodetz Nov 15 '10 at 21:14
  • And downcasting is casting a Base* that points to a Derived back to a Derived*, or a Base& that refers to a Derived back to a Derived& etc., it's not casting instances. I still think the way you're putting it is a tad misleading. – Stuart Golodetz Nov 15 '10 at 21:17
  • @sgolodetz: I agree with each of the points in your comment. I think (I apologize for putting words in your mouth here) the reason you find it misleading is that you think anyone reading it might assume I mean that the object itself is somehow modified by a cast. I suppose I'm just assuming a certain level of knowledge about what casting actually *is* on the part of the reader. – Randolpho Nov 15 '10 at 22:50
  • :) The reason I find it misleading is because you talk about casting *instances* rather than pointers, and I understand an instance of a class to be the actual object, i.e. `Derived d` creates an instance d of class Derived. If you then say `Base b = d`, that slices `d`. The other way round, i.e. `Derived d = b` doesn't work for obvious reasons, and you can't cast it (I said 'shouldn't' before, but actually you can't), i.e. `Derived d = (Derived)b` fails. You can try to hack it, e.g. this compiles: `Derived d = *static_cast(&b)`, but that's evil and does the wrong thing. – Stuart Golodetz Nov 15 '10 at 23:32
  • For (a) above, I should have mentioned that that doesn't actually need a cast, i.e. `Base b = d`, where `d` is a Derived, works fine. – Stuart Golodetz Nov 15 '10 at 23:34