问题是:我有一个源代码,如果由if/else语句填充,旨在执行相同的指令,但在不同类型的数据中。我不喜欢这样,我想为这种不同的数据类型创建一个抽象,在此之前,我可以设置正确的数据类型,然后执行相同的指令。其思想是删除整个if/else语句,这些语句会污染代码。嗯,我做了很多搜索,我的问题的解决方案似乎是与多态性工作。所以,我们在这里。上面是我为执行多态性而创建的类的头文件。其中Platform是基类,Vero和 pioneer 是派生类。
#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 */
在主菜单中,我有这样的内容:
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);
}
到目前为止,一切顺利。但是,之后,在其他地方有:
int a=0;
int b=0;
platform->setmsg(a,b); //WORKS
platform->m_msg; //DOES NOT WOTK
嗯,最后一条语句不起作用,因为基类没有成员变量m_msg,而且我不能创建它,因为它的类型在派生类中是不同的。我也读了关于模板和void指针,但我不能来解决方案。实际上,对于void指针,我可以这样做:
void* platform;
if(which_car.compare("vero")==0){
Vero vero; platform = &vero;
}
else{
Pionner pionner; platform = &pionner;
}
static_cast<Vero*>(platform)->m_msg;
但实际上,这并不能解决我的问题,因为我在强制转换过程中明确指出了类型。
这个问题有什么简单的解决方法吗?对于这个问题,任何其他方法都是受欢迎的。谢谢
如果m_msg
在派生类中可以是不同的类型,那么它就不能在基类中存在。(或者更确切地说,它将被派生类中声明的m_msg
隐藏。)
即使有,编译器也无法在编译时确定它的类型,因此它不知道如何处理语句
platform->m_msg; //DOES NOT WOTK
正如你所说的,模板可以用来解决这个问题。void
指针也可以工作,但是,由于它们缺乏类型安全,除非另一种方法不起作用,否则我不能推荐它们。
另外,m_
用于指示通常是私有的成员变量,所以无论如何,您不应该以这种方式使用它。
同样,这个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);
}
是一个问题,应该提出一些警告。具体来说,在这样的代码块中:
{
Vero vero; platform = &vero;
platform = static_cast<Vero*>(platform);
}
{...}
定义一个局部作用域
你正在创建一个新的Vero
,将它的地址分配给platform
,然后vero
在块的末尾被释放,留下platform
作为一个悬垂指针。(有关更多信息,请参阅Wiki上关于悬空指针的文章。)
同样,语句
platform = static_cast<Vero*>(platform);
为什么要给自己分配平台?