Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Cast parent class to child class

I'm fairly new to C++ and this is the problem I have: I have two classes, Client and Host. And when everything is loaded you have the option to press two buttons, if you press button 1 Client is loaded and if you press button 2 Host is loaded.

Now both Client and Host are fairly big classes, and I don't want to put them both into the memory. So my idea was creating a Base class, and then both Client and Host should extend the base class, and then the only thing I had to do was this:

Base connection;

//If button 1 is pressed:
connection = Client();

//If button 2 is pressed:
connection = Host();

Well this sounded almost too good to be true, and when I tried it I got no errors. Now comes the problem, Base has a function called A, and Client has a function called B. So the function B is unique to the class Client.

When I try to call function B I get this error: 'class Base' has no member named 'B'. How can I let C++ know that I am talking to class Client or Host instead of Base? I am also open for a whole new approach to this problem. Maybe it's just an error in my thinking process.

Thanks in advance!

like image 451
tversteeg Avatar asked Jan 23 '13 23:01

tversteeg


People also ask

Can you cast from parent to child?

However, we can forcefully cast a parent to a child which is known as downcasting. After we define this type of casting explicitly, the compiler checks in the background if this type of casting is possible or not. If it's not possible, the compiler throws a ClassCastException.

Can we typecast parent to child in C#?

This will work because we have cast parent to child and then child to sibling. Parent parent = new Child(); //Assigning child object to parent ref. variable. parent = new Sibling(); // Assigning sibling object to parent.

Can we assign object of parent class to child class?

The parent class can hold reference to both the parent and child objects. If a parent class variable holds reference of the child class, and the value is present in both the classes, in general, the reference belongs to the parent class variable.

Can a child class inherit from a parent class?

Classes called child classes or subclasses inherit methods and variables from parent classes or base classes. We can think of a parent class called Parent that has class variables for last_name , height , and eye_color that the child class Child will inherit from the Parent .


1 Answers

You ran into a situation which we call object slicing, which is a common problem in languages with value semantics such as C++.

Object slicing happens when you assign a value of a sub-type to a new location (your variable connection) of a super type. This introduces a new copy of the instance, but of the super type, not the sub-type, so you lose the information about the concrete class you wanted to instantiate.

To avoid this, you have multiple options.

The classical approach uses pointers:

Base * connection;
connection = new YourConcreteType();

Then, to use this object, you have to derefrerence it using the asterisk operator (*):

(*connection).function();
connection->function();    // syntactic sugar, semantically equivalent

Not to forget: You have to delete the object after usage:

delete connection;

To simplify this, C++ introduces two concepts: references and smart pointers. While the former has a restriction to be only assigned once, it is the syntactically simplest one. The latter is similar to the pointer approach, but you don't have to care about deletion, so you less likely run into a memory leak situation:

std::shared_ptr<Base> connection;

connection = make_shared<YourConcreteType>(); // construction via 'make_shared'

// ... use as if it were just a pointer ...

connection->function();

// no delete!

There are also other "smart pointer" types, like unique_ptr, which can be used if you do not intend to pass the pointer around (if it stays in scope).

Now, you can implement the functions in both classes separately. To make use of polymorphism, this means, during runtime, either the function of the one subclass or of the other subclass is called, depending on which one was constructed, you should declare the functions in the base class as being virtual, otherwise, the function definition in Base will be called, regardless of the concrete type you have constructed.

In your case, you want to call a function which should do something different, depending on the type. While your approach was to introduce two different functions, namely A and B, you can just declare a single function, let's call it handleEvent, as a pure virtual (= abstract) function in the base class, which means "this function is to be implemented in sub classes", and define it in the two subclasses independently:

Base {
    ....
    virtual void handleEvent(...) = 0; // "= 0" means "pure"
};

// Don't provide an implementation

Client {
    void handleEvent(...); // override it
};

// define it for Client:
void Client::handleEvent(...) {
    ...
}

Host {
    void handleEvent(...); // override it
};

// define it for Host:
void Host::handleEvent(...) {
    ...
}
like image 80
leemes Avatar answered Oct 21 '22 23:10

leemes