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!
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:
Then, to use this object, you have to derefrerence it using the asterisk operator (
*):Not to forget: You have to delete the object after usage:
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:
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 inBasewill 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
AandB, you can just declare a single function, let’s call ithandleEvent, 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: