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()函数需要一个变量返回类型”-MakegetBody()
virtual和returnsf:Shape&
,然后子体重写它以返回其body
成员sf::RectangleShape
,sf::CircleShape
,等等都源于sf::Shape
。如果不使用draw()函数,为什么要使用它?除非泄漏该函数返回的所有指针,否则程序的行为是未定义的(因为drawable
的析构函数不是虚拟的).添加否则返回空ptr在string\u to\u object
函数末尾的code>将修复它。我是awar