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

C++ 通过基类指针获取派生成员变量,c++,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::RectangleSha

考虑这个基类:

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");

现在的问题是我需要对形状的主体执行操作/检查,它是派生类的一个成员,我无法从可绘制指针变量访问它。还有一个问题是主体的类型没有设置,它可以是矩形、圆形等,因此getBody()函数需要一个变量返回类型。我怎样才能以一种通用的方式接近尸体?我尝试过模板,但我意识到这不起作用,因为这是一个运行时问题。

听起来您很难确定哪些功能适用于所有
可绘制的
对象,哪些功能适用于
矩形
等等。适用于所有
drawable
对象的属性和方法可以在
drawable
中声明,但任何仅适用于特定类型的
drawable
(如
矩形的宽度和高度与
球的半径之比)的属性和方法都可以在派生类中声明

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

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


抱歉,如果这看起来过于简单-我希望这是清楚的。

听起来您很难确定哪些功能是所有
可绘制的
对象的通用功能,哪些功能是特定于
矩形
等等。适用于所有
drawable
对象的属性和方法可以在
drawable
中声明,但任何仅适用于特定类型的
drawable
(如
矩形的宽度和高度与
球的半径之比)的属性和方法都可以在派生类中声明

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

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


很抱歉,如果这看起来过于简单-我希望它是清楚的。

如果我正确理解了你的问题,有多种方法可以解决这个问题

  • 重新思考你的架构。您可以将每个子类实现的其他虚拟函数引入到drawable中。在这些函数中,您将实现所需的所有检查/操作。因为它们是在基类中实现的,所以它们可以访问形状的主体,并且因为它是基类的虚拟函数,所以可以从外部调用这些函数

  • 由于可绘制对象具有虚拟函数,因此可以使用RTTI在运行时检查类型并执行动态\u转换 见:


  • 只要有可能,我会选择第一个选项。

    如果我正确理解了你的问题,有多种方法可以解决这个问题

  • 重新思考你的架构。您可以将每个子类实现的其他虚拟函数引入到drawable中。在这些函数中,您将实现所需的所有检查/操作。因为它们是在基类中实现的,所以它们可以访问形状的主体,并且因为它是基类的虚拟函数,所以可以从外部调用这些函数

  • 由于可绘制对象具有虚拟函数,因此可以使用RTTI在运行时检查类型并执行动态\u转换 见:


  • 如果可以的话,我更喜欢第一个选项。

    如果不使用draw()函数,为什么会有它?除非泄漏该函数返回的所有指针,否则程序的行为是未定义的(因为
    drawable
    的析构函数不是虚拟的)string_to_object
    函数末尾的code>可以修复它。我知道所有这一切,感谢“我需要对形状的主体执行操作/检查,它是派生类的一个成员,我无法从可绘制指针变量访问”-具体是哪种操作/检查?请用你的问题来说明你想做什么对你不合适。“主体的类型未设置,它可以是矩形、圆形等,因此getBody()函数需要一个变量返回类型”-Make
    getBody()
    virtual和return
    sf:Shape&
    ,然后子体重写它以返回其
    body
    成员
    sf::RectangleShape
    sf::CircleShape
    ,等等都源于
    sf::Shape
    。如果不使用draw()函数,为什么要使用它?除非泄漏该函数返回的所有指针,否则程序的行为是未定义的(因为
    drawable
    的析构函数不是虚拟的).添加
    否则返回空ptrstring\u to\u object
    函数末尾的code>将修复它。我是awar