How would you access derived methods using a base pointer ? - c++

I have seen several posts on this topic, but did not find the kind of solution I am looking for. So sorry at the outset for yet another duplicate. But I want to know what you experts will do faced with a situation as given below ?
class Vehicle // A base class
{
public:
static Vehicle* CreateInstance(const int createWhat)
{
switch(createWhat)
{
case 1:
return new Segway();
break;
case 2:
return new Car();
break;
}
}
};
Now I have a couple of derived classes ..
class Segway : public Vehicle // Segway is a vehicle
{
};
class Sensor
class FuelConsumptionInfo;
class Car : public Vehicle // Car is a vehicle
{
public:
std::list<Sensor>& GetSensorList()
{
return m_pListOfSensors;
}
bool CompareThisCarAgainstOthers(std::list<Vehicle*>& vehicles) const
{
bool isMostEfficientCar = false;
std::list<Vehicle*>::iterator iterVal = vehicles.begin();
while(iterVal != vehicles.end())
{
// 1. Get the list of sensors of this car and compare against the sensors of this car ...
// 2. Get the fuel consumption information and compare against the fuel efficiency of this car ...
}
return isMostEfficientCar;
}
private:
std::list<Sensor*> m_pListOfSensors;
FuelConsumptionInfo* m_FuelEfficiency;
};
And finally I have my favourite car and a set of other cars, and I want to compare my car against them.
int main()
{
std::list<Vehicle*> listOfOtherCars;
Vehicle* pMyFavCar = Vehicle::CreateInstance(2);
listOfOtherCars.push_back(Vehicle::CreateInstance(2));
listOfOtherCars.push_back(Vehicle::CreateInstance(2));
listOfOtherCars.push_back(Vehicle::CreateInstance(2));
listOfOtherCars.push_back(Vehicle::CreateInstance(2));
// How can I invoke the CompareThisCarAgainstOthers without:
// 1. Introducing any base class empty functions ..
// 2. Without using static/dynamic casting to convert the base pointer to a derived class pointer ...
}
As already mentioned in the comments, I want to invoke the CampareThisCarAgainstOthers, but I do not want to cast the base class pointer, nor do I want to introduce any virtual functions in the base class which I think defies the whole logic of having a base class. Even introducing empty virtual base functions will not help because GetSensorList returns a reference to the list.
I will be very thankful to your answers.

The only way to access a child method using a base pointer is by casting the base pointer to a child pointer. This has bad side effects (search the internet for "C++ object slicing").
One issue is that you don't know what kind of child / object the base pointer is pointing to. You could cast the pointer to a wrong child method. Example: a pointer to a Cruise Ship is passed to a function taking a pointer to vehicle. What happens when inside the function, the pointer is cast to a Bicycle type. Clearly, not the same vehicle.
All you can safely access with a pointer to a base class is the public methods and members of the base class. No more, no less.
For example, given a base class of Car and some child classes such as Model_T, Tesla, Hybrid and Mustang, and a pointer to a Car instance, you don't know what kind of car the child is. A Model_T is different than an electric Tesla. A Mustang with a gasoline engine is different than a Hybrid with both electric and gasoline engines.
If you want to access functionality using a base class pointer, put the functionality into the base class as an abstract function. The Car class could have a method virtual bool has_electric_engine(void) const = 0;. The Model_T and Mustang would return false.
Please don't make virtual equality methods into a base class because the code will be comparing attributes, but you really want to compare types. In the example, the Mustang car does not have all the same attributes as the Model_T. Usually, if you need to compare types, your design is flawed.

Related

polymorphism: calling overrided functions without pointers

I am doing some experimentation with C++.
I've been imporessioned by some behaviours with polymorphism.
In other languages (such as c#), when I assign an object based on a derived class to an object of BaseType: this object starts working with the derived class code. Or If I have a list of BaseType objects and I put derived class based objects in it: every element works according to the specific Type.
In c++ no...
I obtained this behaiviour in C++ just using pointers.
Is there an alternative way? Have i missed something?
Here's my code example:
class GenericCar
{
public:
virtual void PrintModelName()
{
std::cout << "No Model Defined \n";
}
};
class FerrariCar : public GenericCar
{
public:
void virtual PrintModelName() override
{
std::cout<<"Ferrari \n";
}
};
int main()
{
std::cout << "Hello World!\n";
//instance of two Ojects: A generic Car (Base Class) and a Ferrari (inherited class)
GenericCar Car = GenericCar();
FerrariCar Ferrari = FerrariCar();
Car.PrintModelName(); //base method
Ferrari.PrintModelName(); //overrided method
((GenericCar)Ferrari).PrintModelName(); //base method....
//declaring a List of Generic Cars (Base Class)
list<GenericCar> ListOfCars;
ListOfCars.push_back(Car); //adding BaseClass based Object
ListOfCars.push_back(Ferrari); //adding InheritedClass based Object
//for each element i want to print the model name of the Car.
for (GenericCar & CarElement: ListOfCars)
{
//The base method is called for each element. (The second object is Ferrari but the base method is executed)
CarElement.PrintModelName();
}
//Now declaring a List of GenericCar pointers
list<GenericCar*> ListOfCarsPointers;
ListOfCarsPointers.push_back(&Car); //adding BaseClass based object address
ListOfCarsPointers.push_back(&Ferrari);//adding InheritedClass based object address
//for each element i want to print the model name of the Car.
for (GenericCar* & CarElement : ListOfCarsPointers)
{
//The correct method is invoked. For the object "Ferrari" is called the overrided function instead of base class code)
CarElement->PrintModelName();
}
//Now i try to assign Ferrari to Car (inherited to base)
Car = Ferrari;//assignment
Car.PrintModelName();//method invoke. Here, the base method is invoked. Not the overridden code...
char c;
std::cin >> c;
}
In C#, for example, the overridden method is called despite the explicit cast to the base class: (BaseClass)InherithedClassObject.method() invokes the overridden method and not the base one.
In the iteration of the list: the overridden method is ivoked, too (Always C#).
In c++ Have I to use always pointer in order to ensure the possibility of having a polymorphic behavior? As a consequence: Have I to manage always memory allocation destroyng objects explicitally?
When you placed Ferrari in your first list you experienced type erasure - the "GenericCar" structure was copied into the list and anything that could have identified that it was a "FerrariCar" was lost.
You need a pointer or reference to invoke polymorphic functions, have a pointer or reference gives you access to the virtual table for your object.
To have a list that could store store such car objects and be passed around to different functions you will probably want to use smart pointers so that you don't wind up with dangling pointers or memory leaks.
#include <memory>
...
list<shared_ptr<GenericCar>> cars;
cars.push_back(shared_ptr<GenericCar>(new GenericCar()));
cars.push_back(shared_ptr<GenericCar>(new FerrariCar()));
for ( shared_ptr<GenericCar> & car : cars )
car->PrintModelName();

When do you need a base class pointer to a derived class object in C++?

I know what is the use of Run Time Polymorphism in an Object Oriented programming language. For example Base class Superhero would be useful to define basic abstract properties of a Superhero that can be inherited and extended in different Super Heroes for example Batman.
I also know that we use inheritance when there is an is-a relationship, for example, Superman is-a Superhero, and we can use a Base class pointer to point to a Derived class object for example...
Superhero *h = new Spiderman();
is valid.
But I want to know what are the circumstances where we would need to do something like this, why can't we just use...
Spiderman *s_man = new Spiderman()
What situation or circumstances would force us to use Base class pointer to hold Child class object.
I would be thankful if someone can make this clear to me.
Having a base class pointing to a derived class allows you to perform operations on groups of base class objects as if they were all the same. In this contrived but marvel cinematic universe conforming example, you could collect all of the avengers in a single list and perform some sort of operation.
std::vector<Superhero*> GetAvengers()
{
std::vector<Superhero*> avengers;
avengers.push_back(new Spiderman());
avengers.push_back(new CaptainAmerica());
avengers.push_back(new IronMan());
avengers.push_back(new Thor());
// ... ad nauseam for three generations of unnecessary standalone films
return avengers;
}
void FightThanos()
{
SuperVillan* thanos = new Thanos();
auto Avengers = GetAvengers();
for(auto&& avenger : Avengers)
{
avenger->SaySomethingSnarky();
avenger->ParticipateInMontageActionSequence(thanos);
}
// Clean up after the avengers, they're not needed for another 4 years
for(auto&& avenger : Avengers)
{
delete avenger;
}
avengers.clear();
}
If you want to have standard calls for all types of super heroes. But the implementation is different. No syntax checking here :)
class Superhero
{
public:
virtual void changeClothes() = 0;
}
class Spiderman : public Superhero
{
public:
void changeClothes()
{
body.wear(spideySuit);
}
};
class Hulk public Superhero
{
public:
void changeClothes()
{
body.shorts.TearApart();
}
};
SuperHero * spidy = (Superhero *) new Spiderman;
SuperHero * hulkster = (Superhero *) new Hulk;
spidey->changeClothes();
hulkster->changeClothes();
Consider a list of superhero pointers. Such a list could store references (pointers) to new Spiderman(), new Superman(), and other objects that inherit superhero.
#lcs has provided an excellent illustration of this concept.

C++ copy constructor issue with parent/child classes

I've run into a problem with copy constructors...I assume there is a basic answer to this and I'm missing something obvious - maybe I'm doing something entirely wrong - but I haven't been able to figure it out.
Basically, I have a parent class and child class. The parent class contains a vector of pointers to a (different) base class object. The child class wants to instead store pointers to objects derived from that base object.
Here's a pseudocode sample, if that helps:
// Base classes
class ItemRev {
...
}
class Item {
protected:
vector<ItemRev *> m_revPtrVec;
}
Item::Item(const Item &inputItemObj)
{
// Copy contents of the input object's item rev pointer vector
vector<ItemRev *>::const_iterator vecIter = (inputItemObj.m_revPtrVec).begin();
while (vecIter != (inputItemObj.m_revPtrVec).end()) {
(this->m_revPtrVec).push_back(new ItemRev(**vecIter));
}
}
=========
// Derived classes
class JDI_ItemRev : public ItemRev {
...
}
class JDI_Item : public Item {
...
}
JDI_Item::JDI_Item(const JDI_Item &itemObj)
{
// Copy contents of the input object's item rev pointer vector
vector<ItemRev *>::const_iterator vecIter = (inputItemObj.m_revObjPtVec).begin();
// The below does not work!
while (vecIter != (inputItemObj.m_revObjPtVec).end()) {
m_revObjPtVec.push_back(new JDI_ItemRev(**vecIter));
}
}
The problem with the above is in the push_back() call in the JDI_Item copy constructor.
Given this setup, what should the child class's copy constructor look like? Do I even need a child class copy constructor? I assumed I did, because the copy constructor is creating new objects, and the parent copy constructor will create new objects that are not the type I want in the derived class (i.e., the parent object stores pointers to ItemRev objects, while the child object should store pointers to derived JDI_ItemRev objects).
As mentioned in the comments, there is probably a more succinct way to express this problem (i.e. your class structure needs some work).
However, if you want to do it this way, the easiest way to achieve it is to use a virtual clone() method in the base class of ItemRev, with overrides of it defined in derived classes.
e.g.:
class ItemRev {
virtual ItemRev* clone() const = 0;
};
class JDI_ItemRev : public ItemRev {
ItemRev* clone() const override
{
// do your actual cloning here, using the copy constructor
return new ItemRev(*this);
}
};
Now, whenever you call clone() on any class derived from ItemRev, you will be returned an ItemRev* but it will point to a fully constructed derived class. You can of course get to the derived class's interface with static_cast<> or dynamic_cast<>.
...however...
derivation often seems like an easy win but it often turns out not to be. Inheritance should only be used if the derived class really is a type of the base class. Often people select inheritance when the derived class is a lot like a base class, or shares many characteristics with a base class. This is not the time to use inheritance. It's the time to use encapsulation.
In general, inheritance is evil.
On another note, you might find this link interesting.
Presentation on inheritance as an implementation detail

storing the instances of the derived class in C++

I saw that many people use new to create instances of the derived classes and then they keep a pointer to base in some container. Does that have any advantage with respect to using a container for each derived class?
With this I meant something like the following
class A
{
public:
vector<Base*> bases;
set<Derived1> der1;
set<Derived2> der2;
//other stuff
};
Edit: removed the second part of the question and added as a comment.
If you do the following
vector<base*> bases;
You can then use polymorphism on your objects.
Imagine that you have a base class named Vehicule. It has a move() method to go from point A to point B.
class Vehicule
{
public:
virtual void move(){}
}
Then you have two derived classes : Car and Submarine
class Car : public Vehicule
{
public:
void move()
{
checktires();
drive();
}
}
And your Sub class
class Submarine : public Vehicule
{
public:
void move()
{
submersion();
propulsion();
}
}
Because the move method is a virtual one, you'll be performing polymorphism. Which is a mechanism that allows you to call the same function but have different behaviours based on the dynamic type of your objects.
I'll try to explain that sentence the best I can.
Now that you have the Vehicule, Car and Submarine classes, you will create an array (or a stl containers like a vector) of Vehicule pointers.
std::vector<Vehicule*> objects;
objects.push_back(new Car());
objects.push_back(new Submarine());
objects[0]->move();
objects[1]->move();
The first call to move will call the move method defined in the Car method. And the second one will call the move defined in Submarine. Because you may have a vector of Vehicule* but when you call the function and because it is virtual, you are calling the appropriate version of it. And by calling only one function you have different behaviours.
You may add as many derived class of Vehicule, you just have to adapt the move method.
You should search stackoverflow for polymorphism, there are far more detailed and accurate answers that the one I just wrote.
Sorry for the mistakes, I'm not a native-english speaker.

C++ - Overuse of virtual methods?

Recently I was given a task where I had to implement something similar to the following:
There are some animals with certain attributes, such as:
Dog1: name: tery, color:white, fav drink: grape juice
Dog2: name: chiva, color:black, fav drink: lemonade
Bird1: name: tweety, canfly: yes, cansing: no
Bird2: name: parry, canfly: no, cansing: yes
How would you do this in C++ efficiently using OOP prractices?
I did something like this:
class Animal {
Animal(...);
...
public String getName() const;
public void setName(string s);
...
private:
String name;
}
class Bird : public Animal {
Bird(...);
public bool canFly() const;
public void setCanFly(bool b);
...
private:
bool canFly;
bool canSing;
}
class Dog : public Animal {
...
}
The problem with this implementation is that i cannot benefit from polymorhism :
Animal* p = new Anima(...);
...
p->canFly();
and I have to use casting:
((Bird*)p)->canFly();
At the end I was criticized of not using virtual functions in base class, and using casts instead of OOP.
But in my opinion it doesn't make sense to use virtual functions here because getName() should be in the base class to avoid multiple implementations of same method. And canFly is not a valid property for dogs for example.
Then I would have to define something absurd like this for each other (future) animal that also inherits from the base class, which would create unnecessary overhead:
bool Dog::canFly () const {
return false;
}
Who is right here, did I not get the basic principles of polymorphism?
Of course 'canFly' is a valid property for a dog, it's just going to return false.
There's no point in having canFly at all if you only implement it when it needs to be true. In your example, by the time you've done your c-style case to a flying animal, then you've already committed to the type of animal, at which point you don't really need to call canFly, because you already know the answer.
If you really don't want to implement canFly in a large number of non-flying animals, then implement virtual bool canFly() const { return false; } in your base class, and just override it in the flying animals.
I'd assume that this is just a contrived 'homework' question, so the answer is bound to look contrived too, but a style which involves lots of casting object types is really going to be bad news in real work.
Well, you don't need a single base class. Consider this:
Animal
|
|--Flying Animal
| |---Bird
|
|--Non Flying Animal
|---Dog
where:
class Animal
{
public:
virtual bool CanFly () = 0;
String Name ();
};
class Flying : public Animal
{
public:
virtual bool CanFly () { return true; }
};
class NonFlying : public Animal
{
public:
virtual bool CanFly () { return false; }
};
class Bird : public Flying
{
};
class Dog : public NonFlying
{
};
There are many other ways to do this as well, even using composition rather than inheritance.
EDIT: Composition. Having a hierarchy where each level in the hierarchy represents a smaller group of members (there are fewer dogs than animals) presents the problem of how to divide the set of all possible types into a hierarchy. As Lagerbaer pointed out in the comments, some birds can't fly.
So instead of creating a complex tree, have a simple tree (or no tree) and have each animal contain a list of characteristics of that animal:
class Animal
{
public:
String Name ();
List <Characteristic> Characteristics ();
};
class Characteristic
{
public:
String Name ();
};
class CanFly : public Characteristic
{
public:
bool CanFly ();
};
class Legs : public Characteristic
{
public:
int NumberOfLegs ();
};
And then, to create a dog:
Animal *CreateDog ()
{
Animal *dog = new Animal;
dog->Characteristics ()->Add (new CanFly (false));
dog->Characteristics ()->Add (new NumberOfLegs (4));
return dog;
}
and to create a bird:
Animal *CreateBird ()
{
Animal *bird = new Animal;
bird->Characteristics ()->Add (new CanFly (true));
bird->Characteristics ()->Add (new NumberOfLegs (2));
return bird;
}
There are two advantages to this:
You can extend it to add whatever characteristics you want.
You can drive the creation of animals from data rather than hard coding it all.
If your language of choice supports reflection, then searching the characteristics list is very straightforward. In non-reflection languages, you'll need to implement some way to identify what each characteristic is.
To address the technical issue, this is wrong:
((Bird*)p)->canFly();
This C-style cast performs a static_cast; if p points to a Dog, the cast will succeed but the result will be incorrect. Bad Things Happen.
When you don't know the most derived type of the pointed-to object and you don't have some way of determining its type via the base class pointer, you need to use dynamic_cast:
if (Bird* bp = dynamic_cast<Bird*>(p)) {
// p points to a Bird
}
else {
// p points to something else
}
dynamic_cast returns a null pointer if the cast fails, allowing you to check the type of the object.
To address the design issue, it depends. In real-world software you can't always have virtual functions in the base class that define the behavior of every possible derived class. It's just not possible. Sometimes it is necessary to dynamic_cast to a derived class to be able to call functions not declared in the base class.
Casts probably were not necessary in this very simple case, but if you were to consider a more complete class hierarchy defining the animal kingdom, you'd find that you would either need an enormous number of functions in the Animal base class or you would have to use casts at some point.
Virtual methods only make sense where there is a need for subclasses to provide their own implementation, or to force them to (pure virtual).
In the case of your canFly and canSing usage, where data members in the base class support invariant implementation in all subclasses, making those get/set methods virtual makes no sense at all to me.
A better candidate for virtual would be the corresponding fly and sing methods, where base class implementation might throw and only when the properties are set true would an animal-specific implementation be provided in a subclass.
struct Animal {
std::string name;
std::string favoriteDrink;
bool canFly;
bool canSing;
};
Feel free to wrap get/setters around the members if it makes you happy.
But one thing people tend to forget is that polymorphism is about behavior. It is about making different classes that look the same, but behave differently.
In this example, there is no different behavior between any of the animals, and so making more than one class is overkill.
There is no actual behavior required for any of the animals. The only operations we need are the ability to ask "what is its name", "can it fly", "can it sing" (and of course, "will it blend?")
All of these operations make as much sense for a penguin as they do on a terrier, a blue whale or a shrew. The behavior is the same, only the data changes. And so it should be one class, with different instances for different animals.
And so trying to split them into separate classes goes against all the goals of OOP: you end up intentionally duplicating code, doing less code reuse, and you're making your code less polymorphic, not more. In my solution, any animal is a drop-in replacement for any other animal. Once you start messing about with different classes and virtual methods, you have to actually write new code for each new animal in order for it to be a suitable implementation of the Animal base class.
If you ever need to add the actual Fly() method, you might need different classes. The mechanics of flying are different for a sparrow, an eagle and a bat (although even this depends on the objective. Depending on what abstraction level the application is working on, the "fly" routine might consist of nothing more than setting another bool flag somewhere, or perhaps giving the animal a positive non-zero altitude, in which case the same implementation is reusable for any flying animal).
But at the moment, all we need is the ability to ask whether or not an animal can fly. And the implementation of that is trivially reusable.
But of course, it's clear from the task you were given that the correct answer (where "correct" is defined as "the I expected when I asked the question" is "use lots of virtual methods for everything, and give everything its own class".
Which just goes to show that the more OOP zealotry you get from someone, the lower the odds that they actually understand OOP.
See also my blog post on the topic
It might be too much in that simple case, but later on you could keep all your animals in a linked list (or standard list or array or whatever) and then iterate over all entries and just call the base methods to do all kinds of stuff without having to worry about casts.
Just think of a simple game with GameObject being the base class and the Methods update() and draw() being virtual. You then inherit other classes, e.g. PlayerObject, EnemyObject, PowerUpObject, etc.
In your main loop you could then do something like this:
GameObject *p = firstObject;
while(p)
{
p->update();
p = p->nextObject;
}
This will iterate over all game objects and call the proper update() methods (e.g. moving the player, letting a power up spin or whatever) and you don't have to do some special casting, e.g. checking to see if it's a player or whatever.
I think you are right. Adding every conceivable property that some family of animals can have to a base class Animal is plain silly and produces too much overhead.
Although it is clear what was intended in the task, i.e., that you really have a virtual function canFly in the base class, I think this is poor design.
Declaring something virtual doesn't stop you implementing it in the base class.
It's a mechanism for saying that you should use the most specific implementation available. It is distinct from over-riding the implementation in the derived class.
Why should returning false from canFly() for a dog be a problem? Some birds can't fly and there are non-birds that can fly.
In my humble opinion, having getter and setter methods is indicative of poor object-oriented design. And this problem space is not particularly conducive to showing off what good object-oriented design is either.