通过基类指针获取派生成员变量

时间:2018-12-03 23:43:44

标签: c++

考虑这个基类:

struct drawable 
{
    virtual void draw(sf::RenderWindow &window) const = 0;

};

和此派生类:

struct rectangle : drawable 
{
  rectangle(sf::Vector2f pos, sf::Vector2f size);
  void draw(sf::RenderWindow &window) const;
  sf::RectangleShape body;
};

对于其他形状(如圆形,直线形和三角形),我也有类似的派生类。我使用此函数基于从文件中获得的文本字符串返回形状:

drawable * string_to_object(std::string name)
{
    if (name == "RECTANGLE")
    {
        return new rectangle(sf::Vector2f(20,20), sf::Vector2f(5,5));
    }
    else if (name == "BALL")
    {
        return new ball(sf::Vector2f(10,10), 5, sf::Vector2f(0,0));
    }
    else if (name == "LINE")
    {
        return new line(sf::Vector2f(30,30), 10, 5);
    }
}

现在在我的主目录中,我有这样的变量来测试它是否有效:

auto game_object = string_to_object("BALL");

现在的问题是,我需要在形状主体上执行操作/检查,该主体是我无法从可绘制指针变量访问的派生类的成员。还有一个问题是没有设置主体的类型,它可以是RectangleShape,CircleShape等,因此getBody()函数将需要一个可变的返回类型。我将如何以一般方式进入身体?我已经尝试过模板,但是我意识到,这是一个运行时问题,因此不起作用。

2 个答案:

答案 0 :(得分:3)

如果我正确理解了您的问题,则有多种方法可以解决此问题。

  1. 重新考虑您的体系结构。您可以向每个子类实现的可绘制对象引入其他虚函数。在这些功能中,您将实现所需的所有检查/操作。由于它们是在基类中实现的,因此可以访问形状的主体,并且由于它是基体的虚拟函数,因此您可以从外部调用这些函数。

  2. 由于可绘制对象具有虚函数,因此可以使用RTTI在运行时检查类型并执行dynamic_cast 参见:https://en.wikibooks.org/wiki/C%2B%2B_Programming/RTTI

只要有可能,我都希望第一种选择。

答案 1 :(得分:0)

听起来好像很难确定所有drawable对象通用的功能,以及rectangleball等特定的功能。可以在drawable内声明适用于所有drawable对象的属性和方法,但是任何仅适用于特定类型drawable的属性和方法(例如rectangle的宽度和高度)与ball的半径)在派生类中。

在您的示例中,如果要实例化它们,则每个派生类必须实现draw方法(因为在基类drawable中将其声明为纯虚拟的) )。这些特定的派生实现中的每一个都可以访问派生类的特定属性。因此,rectangle::draw方法可以访问宽度和高度,而ball::draw方法可以访问半径。

然后,当您有指向drawable对象(实际上是派生类的实例)的指针的集合时,只需为每个对象调用draw方法。

抱歉,这似乎过于简单了-我希望这很清楚。