开发者

downcast problem in c++

开发者 https://www.devze.com 2023-01-25 00:10 出处:网络
#include <iostream> using std::cout; using std::endl; class Base { public : void f(); void g(); int mBaseData1;
#include <iostream>
using std::cout;
using std::endl;
class Base
{
public :
    void f();
    void g();

    int mBaseData1;

};

class Derived : public B开发者_如何学Goase
{
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 ?


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;


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.


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. :)


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


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.
0

精彩评论

暂无评论...
验证码 换一张
取 消