从基类指针访问具有不同类型的两个派生成员变量。

时间:2016-10-05 15:54:53

标签: c++ pointers casting polymorphism

问题在于:我有一个源代码,如果由if / else语句填充,旨在执行相同的指令,但在不同类型的数据中。我不喜欢这个,我想为这种不同的数据类型创建一个抽象,我可以在之前设置正确的数据类型,然后执行相同的指令。我们的想法是删除污染代码的整个if / else语句。好吧,我做了很多搜索,似乎解决我的问题的方法是使用多态。所以,我们来了。上面是我为创建多态而创建的类的标题。这个,平台是基类,另外两个, 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指针,我可以这样做:

void* platform;
if(which_car.compare("vero")==0){
    Vero vero; platform = &vero;
}
else{
    Pionner pionner; platform = &pionner;
}
static_cast<Vero*>(platform)->m_msg;

但事实上,这并没有解决我的问题,因为我明确指出了演员流程中的类型。

这个问题的任何简单解决方案?对此问题的任何其他方法都是受欢迎的。

由于

1 个答案:

答案 0 :(得分: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);

为什么要为自己分配平台?这没用。