Reputation: 785
Here is the problem: I Have a source code that if filled by if/else statements that aims to execute the same instructions but in data with different type. I do not like this, and I would like to create an abstraction for this different data type in which manner that I can set, before, the correctly data type, and then execute the same instructions. The idea is to remove the whole if/else statements that are polluting the code. Well, I did a lot a search and what seems to be the solution of my problem was to work with polymorphism. So, here we are. Above there is the header of the classes that I created to do the polymorphism. The this one, Platform is base class and the other two, Vero and Pionner are the derived ones.
#ifndef VEHICLE_H
#define VEHICLE_H
#include <ros/ros.h>
#include <geometry_msgs/Twist.h>
#include <ransac_project/CarCommand.h>
class Platform{
public:
virtual void setmsg(const double &, const double &) = 0;
//X m_msg; //Some king of genetic type
};
class Vero: public Platform{
public:
ransac_project::CarCommand m_msg;
Vero();
void setmsg(const double &velocity, const double &steering);
};
class Pionner: public Platform{
public:
geometry_msgs::Twist m_msg;
Pionner();
void setmsg(const double &linear_vel, const double &angular_vel);
};
#endif /* VEHICLE_H */
In the main, I have something like this:
Platform* platform;
if(which_car.compare("vero")==0){
Vero vero; platform = &vero;
platform = static_cast<Vero*>(platform);
}
else{
Pionner pionner; platform = &pionner;
platform = static_cast<Pionner*>(platform);
}
So far, so good. But, after, in somewhere else there is:
int a=0;
int b=0;
platform->setmsg(a,b); //WORKS
platform->m_msg; //DOES NOT WOTK
Well, the last statement does not work beacuse the base class does not have the member variable m_msg, and I can not create it, because its type varies in the derived classes. I read also about template and void pointer but I could not come with a solution. In fact with void pointer I could do something like this:
void* platform;
if(which_car.compare("vero")==0){
Vero vero; platform = &vero;
}
else{
Pionner pionner; platform = &pionner;
}
static_cast<Vero*>(platform)->m_msg;
But this, in fact, would not solve my problem since I explicitly pointing out the type in the cast process.
Any easy solution for this problem? Any other approach for this problem is welcome.
Thanks
Upvotes: 1
Views: 46
Reputation: 29051
If m_msg
can be of different types in derived classes, it cannot exist in the base class. (Or rather, it would be hidden by the m_msg
declared in the derived classes.)
Even if it did, the compiler wouldn't be able to determine its type at compile time, so it would have no idea what to do with the statement
platform->m_msg; //DOES NOT WOTK
Templates can be used to address this, as you said. void
pointers also work but, given their lack of type safety, I can't recommend them unless an alternate approach will not work.
Also, m_
is used to indicate member variables that are typically private, so you shouldn't really be using it in this manner, anyway.
Also, this block:
Platform* platform;
if(which_car.compare("vero")==0){
Vero vero; platform = &vero;
platform = static_cast<Vero*>(platform);
}
else{
Pionner pionner; platform = &pionner;
platform = static_cast<Pionner*>(platform);
}
Is a problem and should be raising some warnings. Specifically, in a block like this:
{
Vero vero; platform = &vero;
platform = static_cast<Vero*>(platform);
}
{...}
define a local scope.
You're creating a new Vero
, assigning the address of it to platform
, then vero
is freed at the end of the block leaving platform
as a dangling pointer. (See the Wiki article on dangling pointers for more information.)
Also, the statement
platform = static_cast<Vero*>(platform);
Why are you assigning platform to itself? This is useless.
Upvotes: 1