从基类指针访问两个具有不同类型的派生成员变量。
Posted
技术标签:
【中文标题】从基类指针访问两个具有不同类型的派生成员变量。【英文标题】:Get access from base class pointer to two derived member variables that has different types. 【发布时间】:2016-10-05 15:54:52 【问题描述】:问题是:我有一个源代码,如果由 if/else 语句填充,旨在执行相同的指令,但数据类型不同。我不喜欢这样,我想为这种不同的数据类型创建一个抽象,我可以在此之前设置正确的数据类型,然后执行相同的指令。这个想法是删除污染代码的整个 if/else 语句。好吧,我做了很多搜索,似乎我的问题的解决方案是使用多态性。所以,我们到了。上面是我为执行多态性而创建的类的标题。这一个 Platform 是基类,另外两个 Vero 和 Pionner 是派生类。
#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* platform;
if(which_car.compare("vero")==0)
Vero vero; platform = &vero;
else
Pionner pionner; platform = &pionner;
static_cast<Vero*>(platform)->m_msg;
但事实上,这并不能解决我的问题,因为我在转换过程中明确指出了类型。
这个问题有什么简单的解决方案吗?欢迎任何其他解决此问题的方法。
谢谢
【问题讨论】:
Vero vero; platform = &vero;
只要if()
块离开,指针就会悬空。
在 Vero 类和 Pionner 类中也将 setmsg() 定义为 virtual,因此抽象成员函数 setmsg() 被覆盖
工厂方法是另一种解决类型问题的方法,方法是注册继承的对象并预分配相应的成员函数
【参考方案1】:
如果m_msg
在派生类中可以是不同的类型,则它不能存在于基类中。 (或者更确切地说,它会被派生类中声明的m_msg
隐藏。)
即使是这样,编译器也无法在编译时确定其类型,因此它不知道如何处理该语句
platform->m_msg; //DOES NOT WOTK
正如您所说,模板可用于解决此问题。 void
指针也可以工作,但由于它们缺乏类型安全性,我不推荐它们,除非替代方法不起作用。
另外,m_
用于表示通常是私有的成员变量,因此无论如何您都不应该以这种方式使用它。
还有,这个块:
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 article on dangling pointers。)
还有,声明
platform = static_cast<Vero*>(platform);
为什么要为自己分配平台?这是没用的。
【讨论】:
原代码有点不同,其实平台变量是其他类的成员变量。无论如何,您对如何解决这个问题有什么建议吗? @Randerson 在您的消息类型的基类、通用基类或接口中模板化了setmsg
。以上是关于从基类指针访问两个具有不同类型的派生成员变量。的主要内容,如果未能解决你的问题,请参考以下文章