A Way of Casting a Base Type to a Derived Type

Convert base class to derived class

No, there's no built-in way to convert a class like you say. The simplest way to do this would be to do what you suggested: create a DerivedClass(BaseClass) constructor. Other options would basically come out to automate the copying of properties from the base to the derived instance, e.g. using reflection.

The code you posted using as will compile, as I'm sure you've seen, but will throw a null reference exception when you run it, because myBaseObject as DerivedClass will evaluate to null, since it's not an instance of DerivedClass.

A way of casting a base type to a derived type

Not soundly, in "managed" languages. This is downcasting, and there is no sane down way to handle it, for exactly the reason you described (subclasses provide more than base classes - where does this "more" come from?). If you really want a similar behaviour for a particular hierarchy, you could use constructors for derived types that will take the base type as a prototype.

One could build something with reflection that handled the simple cases (more specific types that have no addition state). In general, just redesign to avoid the problem.

Edit: Woops, can't write conversion operators between base/derived types. An oddity of Microsoft trying to "protect you" against yourself. Ah well, at least they're no where near as bad as Sun.

Unable to cast base class to derived class

In Case two you have an instance of dog and animal

Animal a = new Animal();
Dog d = new Dog();

Then you have reference copy of dog to animal

a = d;

So the a is points to d and d is a dog instance and instance properties like noOfTail is still exist but is hidden and not available in object a.
and then you have this line :

d = (Dog)a;

In last line you have reference copy of d to a ,so d is point to where a is point to so everything is okay.

but in case one you want copy one Instance of child class Dog to an instance of Animal so the properties of child class will be lost. you need to confirm that with Compiler and say to him you know instance properties like noOfTail will not be available any more
your code most be like this :

 Animal a = new Animal();
Dog d = new Dog();
d = (a as Dog);

Typecasting to a Base Class

It means you don't need to explicitly cast the derived object to the base type.

DerivedClass derived1 = new DerivedClass();

// This is an implicit coversion:
BaseClass base1 = derived1;

// This is an explicit conversion:
DerivedClass derived2 = (DerivedClass) base1;

Regardless of how you convert, you can't call a method defined in a derived class from a variable of the base type. To call a method from a derived type, you'd need to explicitly cast to that type:

((DerivedClass) base1).derived_name();

Casting Generic base object to derived type

A reference declared as BaseSettings<T> may or may not refer to an actual instance of Settings1Manager. That's how inheritance works. In fact though, what you're doing is casting a base type reference that's actually referring to an object that you've just confirmed actually is of the derived type.

settings as Settings1Manager will compile, because as will just return null if the cast fails. You and I know that particular cast won't fail, but the compiler just follows its rules.

if (typeof(Settings1Manager).IsAssignableFrom(settings.GetType()))
{
return WriteSettings1ManagerToNetwork(settings as Settings1Manager);
}

This works too, because you can cast anything to object and you can cast object to anything. But you don't want people seeing your name on code that looks like this.

return WriteSettings1ManagerToFile((Settings1Manager)(object)settings);

Convert a base class to a derived class

This happens because BaseClass is not an instance of DerivedClass (but DerivedClass is an instance of BaseClass), so you cannot cast an instance of the base class as an instance of the derived class (well, you can, but it will be null as you have found).

You can do what (I think) you are trying to achieve by adding a constructor to the derived class that takes in the base class as a parameter:

public DerivedClass(BaseClass baseClass) {
// Populate common properties, call other derived class constructor, or call base constructor
}

Then:

 DerivedClass dc = new DerivedClass(MethodThatReturnsBaseClassObject());

Convert/Cast base type to Derived type

You can't. If results doesn't refer to a MyResults (e.g. if CallFrameworkMethod returns a base Results instance), then casting won't make it so: you'll need to create a new MyResults, based on the existing non-MyResults. Casting is about changing the compile-time type of the reference, not about changing the concrete type of the referenced object.

You can use tools such as Reflection or AutoMapper to help with the initialisation of the new MyResults object -- but a new MyResults object there must be, because you cannot tell a base Results object to become a MyResults object.

Why doesn't this code cast a base class into a derived class in c++?

Whenever you push an object of b into vector vec of Base Objects, you create another object from temp which is purely of type base. You might be thinking (and you are not right!) that element which is being stored in vector will be of type Base but it will be holding an object of type bbut it's not how you achieve Dynamic Polymorphism in C++.

The statements:

std::vector<Base> vec; // 1
b temp; // 2
vec.push_back(temp); // 3

The third line will create a different object to type Base by calling assignment operator of base class Base operator=(const Base& ).

Also,b* temp = (b*)&vec[i]; is an undefined behavior because you are explicitly trying to cast a pointer to object of base to it's derived class type b but it doesn't hold object of type b and hence, you may get unexpected behavior.

NOTE:

Use dynamic_cast for casting between base and derived class as it will make sure that the conversion is valid. Otherwise, it will return nullptr. However, you need to make your base class polymorphic by having at least 1 virtual function.

If the cast is successful, dynamic_cast returns a value of type new-type. If the cast fails and new-type is a pointer type, it returns a null pointer of that type. If the cast fails and new-type is a reference type, it throws an exception that matches a handler of type std::bad_cast.

SOLUTION:

Use vector of pointers to base class to achieve run-time polymorphism.

std::vector<base *> vec;
for (int i = 0; i < 5; i++) {
b *temp = new b();
vec.push_back(temp);
}

for (int i = 0; i < 5; i++) {
b* temp = dynamic_cast<b *>(vec[i]); // For dynamic cast, you need to add virtual functions to your base class
if (temp != nullptr)
std::cout << temp->d << std::endl;
}

EDIT:

Object Slicing is also a solution for your problem. Object Slicing is the right keyword for this type of problems. Here is the definition of the Object Slicing

Object slicing happens when a derived class object is assigned to a base class object, additional attributes of a derived class object are sliced off to form the base class object.

I am quoting one of the answer in the link below. See this answer and answer for the best explanation and possible solution with some code snippet. See this article, it has explained the problem when pushing object of Derived class in a vector of base class.

"Slicing" is where you assign an object of a derived class to an instance of a base class, thereby losing part of the information - some of it is "sliced" away.

For example,

class A {
int foo;
};

class B : public A {
int bar;
};

So an object of type B has two data members, foo and bar.

Then if you were to write this:

B b;
A a = b;

Then the information in b about member bar is lost in a.

C++ Type casting base object to derived object

dynamic_cast returns the casted pointer, it does not modify the parameter itself.

You need to do something like below.

// removed the & since the elements are now pointers
GradStudent* gStudent = dynamic_cast<GradStudent*>(classRoom[1]);
cout << gStudent->getInfo();

Caveat - for pointers, if it fails to cast dynamic_cast will return nullptr, you need to check for this to prevent a crash.

EDIT: Major Object slicing bug in your code - #1 is almost right

int arraySize = 3;
Student *classRoom;
classRoom = new Student[arraySize];

GradStudent gst1("Ta", "Da", 4444, 'A', "Death");
...
classRoom[0] = gst1;

Should be

int arraySize = 3;
Student **classRoom;
// ^
classRoom = new Student*[arraySize];
// ^
GradStudent gst1("Ta", "Da", 4444, 'A', "Death");

classRoom[0] = &gst1;
// ^

Or just

Student* classRoom[3];

GradStudent gst1("Ta", "Da", 4444, 'A', "Death");
...
classRoom[0] = gst1;

Without this, all data belonging to the derived class is lost, and the base class data alone is stored, this is called Object Slicing.



Related Topics



Leave a reply



Submit