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

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 是基类,另外两个 VeroPionner 是派生类。

#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 = &amp;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

以上是关于从基类指针访问两个具有不同类型的派生成员变量。的主要内容,如果未能解决你的问题,请参考以下文章

如何使用多态性从基类访问派生类向量成员?

c ++设计:从基类转换为派生类,没有额外的数据成员

从基类到派生类的静态转换后找不到成员函数

多态性:从基指针访问派生成员函数

C++派生类是不是可以从基类继承静态数据成员和静态成员函数?

5继承与派生2-访问控制