Calling function from derived class through base class that is not overridden - c++

in C++;
Is there a way of calling a function from a derived class through the base class
even when the function is not overridden? In other words, I'm using a base class in
order to have heterogeneous containers without boost; I want to call a member function
that is only specific to a derived class...
Example:
(I just made this code up so there's probably a syntax error but hopefully you get the gist)
class Vehicle
{
public:
virtual void do_vehicle_stuff();
// virtual void do_car_specific_stuff(); makes no sense here
}
class Car : public Vehicle
{
public:
void do_vehicle_stuff();
void do_car_specific_stuff();
}
Car a,b;
list<Vehicle> vehicle_list;
vehicle_list.push_back(a);
vehicle_list.push_back(b);
vehicle_list.front().do_car_specific_stuff();
error: 'Class Vehicle' has no member named 'do_car_specific_stuff()'

You are slicing your classes when you insert them into the list. In
C++ subtype polymorphism (the kind of polymorphism you are using) only
works through references or pointers but not values. When you insert
your carS into the list they are converted to VehicleS.
An example:
Car c;
std::vector<Vehicle> vs;
vs.push_back(c); // slicing happens
vs.front(); // not a car anymore, but just a vehicle,
// the Car-ness is lost through the copy operation
How do to it:
std::vector<std::unique_ptr<Vehicle>> vs;
vs.push_back(new Car());
vs.front(); // actually a Car
After you have resolved that fundamental flaw of your code, this might
help you:
Vehicle* vehiclep = new Car();
if(auto carp = dynamic_cast<Car*>(vehiclep)) {
carp->do_car_specific_stuff();
}
This is a rather costly operation and usually an indication of a
design smell, so you might want to rethink what you are doing.

Here's a more appropriate design:
struct Vehicle
{
virtual ~Vehicle() { }
void do_vehicle_stuff()
{
vehicle_impl();
}
private:
virtual void vehicle_impl() = 0;
};
struct Car : Vehicle
{
private:
virtual void vehicle_impl()
{
my_vehicle_stuff();
my_car_specific_stuff();
}
void my_vehicle_stuff() { /* what you had originally */ }
void my_car_specific_stuff() { /* car-only stuff */ }
};
std::list<std::unique_ptr<Vehicle>> vehicles;
vehicles.emplace_back(new Car);
vehicles.emplace_back(new Motorcycle);
vehicles.emplace_back(new Carriage);

Related

How to access derived class member function using Base class function?

I am trying to design a parking system (Low-level Design )
Some classes behave like this.
class Vehicle
{
public:
int entryTime;
int exitTime;
virtual void leaveParking(Vehicle*);
virtual int getChargePerHr();
//virtual void getChargePerHr() = 0;
Vehicle() {}
};
class Car : public Vehicle
{
private :
int chargePerHr = 30;
public:
void leaveParking(Vehicle*);
int getChargePerHr();
Car(){}
};
class Bike : public Vehicle
{
private :
int chargePerHr = 10;
public:
void leaveParking(Vehicle*);
int getChargePerHr();
Bike(){}
}
void Vehicle ::leaveParking(Vehicle* v)
{
int pay = v-> // Here expecting Car class member function getChargePerHr() should come
//so that I can access private member chargePerHr of car class.
// But I am not able to access the Car class member function here.
}
int main()
{
Car c1; // assume Car c1 has already parked.
Vehicle v;
Vehicle* vptr = new Vehicle();
vptr = new Car();
c1.leaveParking(vptr); // Car c1 wants to leave the parking place
}
I want to access getChargePerHr() of Car class using Base class Vehicle member function.
I tried with pure virtual function but still could not make it.
Could anyone help me?
Problem
Here:
void Vehicle::leaveParking(Vehicle* v)
{
...
}
You're not able to access Car::getChargePerHr() because v is a Vehicle not a Car.
Clearly you're attempting to achieve polymorphism since it appears you want derived classes of Vehicle to perform the same actions when they leave parking.
Solution
Declare Vehicle::getChargePerHr() as pure virtual (or virtual if you want a default implementation)
Provide implementations of getChargePerHr() in your derived classes
Implement Vehicle::leaveParking() using just the methods you've defined in Vehicle
At runtime, the virtual table will resolve overrides and call the correct derived implementation.
Other Issues
You are inheriting from Vehicle without declaring its destructor virtual. This means if any child classes need to perform clean-up, their destructors won't be called.
You're missing a semicolon after the Bike class declaration.
If every Vehicle does the same thing when leaving parking, it doesn't make sense to have leaveParking() be virtual—you make a member function virtual if you want it to be able to be overridden by child classes.
Vehicle::leaveParking() should probably not be taking another Vehicle as a parameter. The function acts on the vehicle itself, not on a different one.
If your constructor is empty, it's better to leave it out of the class declaration since it can confuse others who might read your code.
And many more issues. I suggest you take aalimian's advice to read up on C/C++. Your code shows many misunderstandings.
Code
Putting everything together, here's an example:
class Vehicle
{
public:
int entryTime;
int exitTime;
virtual ~Vehicle() = default;
void leaveParking();
virtual int getChargePerHr() = 0;
};
void Vehicle::leaveParking()
{
// This will call a derived class's implementation
int pay = getChargePerHr();
// Do more vehicle stuff
}
class Car : public Vehicle
{
private:
int chargePerHr = 30;
public:
int getChargePerHr() override;
};
int Car::getChargePerHr()
{
return chargePerHr;
}
class Bike : public Vehicle
{
private:
int chargePerHr = 10;
public:
int getChargePerHr() override;
};
int Bike::getChargePerHr()
{
return chargePerHr;
}
You can see this in action here.

Accessing subclass methods in array of pointers

I've been having trouble accessing the "getDegreeProgram()" method in my objects that are set to my array of pointers; all of my baseclass methods are working, but for some reason, my subclass methods aren't even visible. I'm suspecting that I don't have the syntax right, and its converting all of my subclass objects to the baseclass of student.
roster.h:
class roster {
private:
student** classRosterArray; //array of pointers
roster.cpp function that creates my objects and sets them to the array of pointers
void roster::createStudentObject() {
classRosterArray = new student *[5]; //array of pointers
if (degreeProgramInput == "NETWORK") {
classRosterArray[rosterCounter] = new networkStudent();
}
else if (degreeProgramInput == "SECURITY") {
classRosterArray[rosterCounter] = new securityStudent();
}
else classRosterArray[rosterCounter] = new softwareStudent();
}
student.h subclasses in question (they're subclasses of my baseclass "student")
class networkStudent:public student {
private:
int networkDegree;
public:
int getDegreeProgram();
networkStudent();
};
class securityStudent:public student {
private:
int securityDegree;
public:
int getDegreeProgram();
securityStudent();
};
class softwareStudent:public student {
private:
int softwareDegree;
public:
int getDegreeProgram();
softwareStudent();
};
As far as I understood, you are trying to access the elements of classRosterArray and trying to call getDegreeProgram().
For this problem, Make the getDegreeProgram() virtual function.
student.h
class student {
...
public:
virtual int getDegreeProgram() = 0; // pure virtual function
};
Subclasses of student
class networkStudent:public student {
private:
int networkDegree;
public:
virtual int getDegreeProgram();
networkStudent();
};
class securityStudent:public student {
private:
int securityDegree;
public:
virtual int getDegreeProgram();
securityStudent();
};
class softwareStudent:public student {
private:
int softwareDegree;
public:
virtual int getDegreeProgram();
softwareStudent();
};
Suggestion:
In this case, Because getDegreeProgram() seems to be a getter function, I think you should declare it as a const function.
Edit:
As rightly said by Richard, In C++ 11, override keyword was introduced for this purpose for the sub classes. So, instead of writing virtual int getDegreeProgram();, you could write int getDegreeProgram() override; also.
There are two you ways you can go about it.
Runtime Polymorphism - This method will require less code refactoring but at the cost of runtime. Each instance of a polymorphic class will have a pointer(vptr) to a table(vtable) of pointers to the different versions of the virtual function. This table will be used for finding the right version of the virtual function at runtime.
You can achieve runtime polymorphism here by making the getDegreeProgram function virtual in base class ie., Student and override it in derived classes ie., securityStudent, networkStudent and softwareStudent.
class Student {
...
public:
virtual int getDegreeProgram() = 0; // notice the virtual keyword and 0 at the end.
// 0 is for saying that it is pure virtual, meaning
// we don't have any definition for this function in
// this class. Such a class is also called as
// abstract class
...
}
class securityStudent : Student {
...
public:
int getDegreeProgram() override
{
// do the stuff you want to do
}
...
}
// driver stub
...
Student *student;
securityStudent sStudent;
networkStudent nStudent;
.
.
student = &sStudent;
student->getDegreeProgram(); // calls security student implementation of getDegreeProgram
student = &nStudent;
student->getDegreeProgram(); // calls network student implementation of getDegreeProgram
...
Static Polymorphism or CRTP or Simulated Dynamic Binding - This method does the same thing as above but with the advantage of knowing the type at compile time by means of some casting magic (below). Even this approach has its limitation like kludgy syntax and some amount of refactoring which is a lot more than in the 1st case and lack of readability due to terseness of templates etc.
The trick here is to get the derived class' information at compile time and typecast the this pointer of the base class to that of the derived class. :-)
template <typename StudentType>
class Student {
...
public:
int getDegreeProgram()
{
return (static_cast<StudentType*>(this))->getDegreeProgramImpl();
}
...
}
class securityStudent : public Student<securityStudent> {
...
public:
int getDegreeProgramImpl()
{
// write your specifc implementation here
}
...
}
// driver stub
...
securityStudent sStudent;
networkStudent nStudent;
.
.
sStudent.getDegreeProgram(); // calls security student implementation of getDegreeProgram
nStudent.getDegreeProgram(); // calls network student implementation of getDegreeProgram
...

C++: Extend member type in derived class

I'd welcome some help with C++ inheritance to get a better grasp of the concept.
Is it possible to "extend" member types when creating a derived class? I think my problem can be best demonstrated by a simple example, where I'd like to extend the class VehicleData with a new double variable:
class VehicleData {
int yearOfManufacture;
//Different routines, for example Serialize(), etc., warranting to create a class for just a bunch of variables
};
class BicycleData:VehicleData {
double frameHeight; //new property that only applies to bicycles
};
//Now I create the actual classes that use the types above
class Vehicle {
VehicleData data;
void PrintData(); //a function that works on basic vehicle data
};
class Bicycle:Vehicle {
BicycleData data; //should copy VehicleData when creating an instance of this class
};
The problem with this approach is that when I code the above and create a Bicycle instance, its BicycleData member hides the already existing VehicleData member.
Is there a way to extend the base class, i.e. simply add a new double variable (to store frame height in this example), and keep the already existing (year of manufacture) data?
As far as I can tell, there is no clean way to do exactly what you want with inheritance alone.
You could create a template out of your base class:
template <typename Data>
class BaseVehicle
{
Data data;
// etc.
};
class Vehicle : BaseVehicle<VehicleData>
{
// etc.
};
class Bicycle : BaseVehicle<BicycleData>
{
// etc.
};
Then the Vehicle and Bicycle classes would contain data field of VehicleData and BicycleData types respectively.
Since in your example Bicycle inherits from Vehicle privately (i.e. there is no support for using Bicycle polymorphically via pointer/reference to Vehicle), this would effectively be identical to what you want to achieve.
If you do want dynamic polymorphism, you should create a separate, preferably abstract, class, defining the interface for your vehicles, e.g.:
class VehicleInterface
{
public:
// Some pure virtual interface methods
virtual void moveTo(const Vector2 position) = 0;
virtual ~VehicleInterface() = default;
};
And then you can have your concrete vehicles inherit and implement this interface:
class Vehicle : BaseVehicle<VehicleData>, public VehicleInterface
{
public:
virtual void moveTo(const Vector2 position) override
{
// implementation for Vehicle
}
};
class Bicycle : BaseVehicle<BicycleData>, public VehicleInterface
{
public:
virtual void moveTo(const Vector2 position) override
{
// implementation for Bicycle
}
};
Then any function, which would like to work with vehicles polymorphically, can just accept a reference or a pointer to VehicleInterface:
void driveToWork(VehicleInterface* vehicle)
{
vehicle->moveTo(getWorkPosition());
// etc.
}
Short answer; Not in the way that you're aiming for, but you can achieve something similar.
Rather than have an instance declared as you have, if you make data a pointer. You can then have BicycleData inherit VehicleData and then just replace data with the new instance in the constructor of the Bicycle.
ie
class Vehicle {
void PrintData();
protected:
void replaceData(std::shared_ptr<VehicleData> d) {
data = d;
}
std::shared_ptr<VehicleData> getData() {
return data;
}
template<class T>
std::shared_ptr<T> getDataAs() {
return std::dynamic_pointer_cast<T>(data);
}
private:
std::shared_ptr<VehicleData> data;
};
class Bicycle:Vehicle {
Bicycle(){replaceData(std::make_shared<BicycleData>());}
std::shared_ptr<BicycleData> getData() {
return getDataAs<BicycleData>();
}
};

Parent class referencing child variable

I have several similar classes inheriting from the same Base-Class/Interface (Base class 1), and they share a couple similar functions, but then also have their own distinct functions. They all also have their own member variables of different classes, and each of those inherits from the same Base-Class/Interface (Base class 2). Is it possible to define a variable in Base class 1, of type Base class 2, then in the actual implementation of classes using Base class 1, have the variable of type Base class 2 be its proper type. Kinda hard to explain, so simplified example below.
//Base-Class 1
class Shape
{
public Shape() {}
ShapeExtra m_var;
//The common functions
public GetVar(){ return m_var; }
}
class Circle : Shape
{
public Circle() { m_var = new CircleExtra(); }
public void CircleFunc()
{
m_var.CircleExtraFunc();
}
}
class Triangle : Shape
{
public Triangle() { m_var = new TriangleExtra(); }
public void TriangleFunc()
{
m_var.TriangleExtraFunc();
}
}
.
.
.
//Base_Class 2
class ShapeExtra
{
public ShapeExtra() {}
}
class CircleExtra : ExtraClass
{
public CircleExtra() {}
void CircleExtraFunc() {//Do stuff}
}
class TriangleExtra : ExtraClass
{
public TriangleExtra() {}
void TriangleExtra() {//Do stuff}
}
.
.
.
So, I need the m_var in the child classes to be kept it as its own unique version. Because right now (w/o the extra CircleExtra m_var;), the GetVar() works, but in CircleFunc, m_var is still type of ShapeExtra, and thus doesn't know that CircleExtraFunc exists. I could cast m_var each time I wanted to do that, but that is repetitive and not worth it in my real-world case. Is there a way to utilize the functions in unique classes based off of ShapeExtra, while keeping the GetVar() function in Shape?
Please ask questions if there is anything I left out.
Simply with inheritance and without using pointers it is not possible, as C++ is a statically-and-strictly-typed language.
You can inherit both the variable and the function, but you'll need to cast function return value.
You can also override the function to make it return the concrete type, but then you have to cast the variable inside the function.
You can also declare the same var with the concrete class in subclasses, but then you just hide the variable in the superclass and inherit nothing.
I'd rather go for a solution using templates. Make the type of the variable a template type and extend the template using a concrete type in subclasses. It'll work perfectly.
It's been a long time since I last programmed in C++ and I beg your pardon if there are errors in the following example. I'm sure you can easily make it work.
template <class S>
class Shape {
S m_var;
//......
public:
S var () {
return m_var;
}
//.......
}
class Circle: Shape <CircleExtra> {
// var method returns CircleExtra
//......
}
Edit:
Regarding some comment, to allow virtual invocation of the method, it is possible to use correlated return types. Something like the following example.
class Shape {
public:
virtual ShapeExtra *var () = 0;
}
template <typename SE>
class ConcreteShape: Shape {
public:
virtual SE *var() {
return &m_var;
}
// Constructor, etc.
private:
SE m_var;
}
Or some variation. Now concrete shapes can benefit from extending the template, as long as SE * is correlated with ShapeExtra * (the type parameter extends ShapeExtra). And you can vall the method transparently through Shape interface.
Using pointers, this is totally possible.
Using your example, you could do something like this:
#include <iostream>
#include <memory>
using namespace std;
//Extras
class ShapeExtra
{
public:
ShapeExtra() {}
void ShapeFunc() { std::cout << "Shape"; }
virtual ~ShapeExtra() = default; //Important!
};
class Shape
{
public:
std::unique_ptr<ShapeExtra> m_var;
//require a pointer on construction
//make sure to document, that Shape class takes ownership and handles deletion
Shape(ShapeExtra* p):m_var(p){}
//The common functions
ShapeExtra& GetVar(){ return *m_var; }
void ShapeFunc() {m_var->ShapeFunc();}
};
class CircleExtra : public ShapeExtra
{
public:
void CircleExtraFunc() {std::cout << "Circle";}
};
class Circle : public Shape
{
CircleExtra* m_var;
public:
Circle() : Shape(new CircleExtra()) {
m_var = static_cast<CircleExtra*>(Shape::m_var.get());
}
void CircleFunc()
{
m_var->CircleExtraFunc();
}
};
int main() {
Circle c;
//use the ShapeExtra Object
c.GetVar().ShapeFunc();
//call via forwarded function
c.ShapeFunc();
//call the circleExtra Function
c.CircleFunc();
return 0;
}
Test it on ideone
Note the use of pointers and a virtual destructor:
By using a virtual destructor in the ShapeExtra base class, you make it possible to destruct an object of any derived class, using a ShapeExtra*. This is important, because
by using a std::unique_ptr<ShapeExtra> instead of a plain C-pointer, we make sure that the object is properly deleted on destruction of Shape.
It is probably a good idea to document this behaviour, i.e. that Shape takes the ownership of the ShapeExtra*. Which especially means, that we do not delete CirleExtra* in the Circle destructor
I decided here to require the ShapeExtra* on construction, but its also possible to just use std::unique_ptr::reset() later and check for nullptr on dereferencing Shape::m_var
Construction order is this: On calling the constructor of Circle, we first create a new CircleExtra which we pass to Shape before finally the constructor of Circle is executed.
Destruction order is Circle first (was created last), then Shape which also destructs the ShapeExtra for us, including (via virtual function) the CircleExtra
I would recommend the following approach:
class ShapeExtra
{
public:
virtual ~ShapeExtra() { }
virtual void SomeCommonShapeFunc() { std::cout << "Shape"; }
};
class Shape
{
public:
virtual ShapeExtra &GetVar() = 0; // Accessor function.
};
Note that the class Shape does not have any data members at all. After that for each derived class you need:
class CircleExtra : public ShapeExtra
{
public:
void SomeCommonShapeFunc() { std::cout << "Circle"; }
};
class Circle : public Shape
{
CircleExtra m_var; // Data member with circle specific class.
public:
virtual ShapeExtra &GetVar() { return m_var; }
};
Implementation of virtual method in Circle will return reference to the base class ShapeExtra. This will allow using this extra in the base class.
Note that pointers and templates are not used at all. This simplifies the overall design.

Calling virtual method from base class C++

I'm new to C++ and i'm having a hard time figuring out what's wrong with my virtual functions. So, here's what i have:
GEntity.h
class GEntity
{
public:
//...
virtual void tick(void);
virtual void render(void);
//...
};
GEntity.cpp
//...
void GEntity::tick(void){}
void GEntity::render(void){}
//...
GLiving.h
class GLiving : public GEntity
{
public:
//...
virtual void tick(void);
virtual void render(void);
//...
};
GLiving.cpp
//...
void GEntity::tick(void){}
void GEntity::render(void){}
//...
Then i have other classes that derive from GLiving (Player, Enemy) which implement their own versions of this two methods:
Player.h
class Player : public GLiving
{
public:
//...
void tick(void);
void render(void);
//...
};
Player.cpp
//...
void GEntity::tick(void)
{
//Here there's some actual code that updates the player
}
void GEntity::render(void)
{
//Here there's some actual code that renders the player
}
//...
Now, if i declare an object of class Player, and call the render/tick method, everything goes well, but i am in a situation in which i add my player to an arraylist (a struct i created) of GEntity, and then, when i get it back, i get it as a GEntity, and i need to call the render/tick methods without knowing it's derived class...
I've tried with the code above, but i get an access violation in the line where i call either the render or tick method, on the extracted GEntity...
...is what i want even possible to achieve?
(sorry if my english is not so good, but i'm italian)
If you have an array of GEntity then, each time you "add" a derived type, the equivalent of this happens:
GEntity g;
Player p;
g = p; // object slicing, you assigned a Player to a GEntity object.
g.render(); // GEntity::render() gets called
On the other hand, you can use a pointer to a base class to access a derived method:
GEntity* g;
Player p;
g = &p;
g->render(); // calls Player::render()
So a way to deal with polymorphism in containers is to have arrays/containers of (preferably smart) pointers to the base class. This example uses raw pointers for simplicity, but you should use smart pointers in real code:
std::vector<CEntity*> entities;
entities.push_back(new Player);
entities.push_back(new GLiving);
// some c++11
for ( auto e : entities) {
e->render();
}