考虑这个基类:
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()函数将需要一个可变的返回类型。我将如何以一般方式进入身体?我已经尝试过模板,但是我意识到,这是一个运行时问题,因此不起作用。
答案 0 :(得分:3)
如果我正确理解了您的问题,则有多种方法可以解决此问题。
重新考虑您的体系结构。您可以向每个子类实现的可绘制对象引入其他虚函数。在这些功能中,您将实现所需的所有检查/操作。由于它们是在基类中实现的,因此可以访问形状的主体,并且由于它是基体的虚拟函数,因此您可以从外部调用这些函数。
由于可绘制对象具有虚函数,因此可以使用RTTI在运行时检查类型并执行dynamic_cast 参见:https://en.wikibooks.org/wiki/C%2B%2B_Programming/RTTI
只要有可能,我都希望第一种选择。
答案 1 :(得分:0)
听起来好像很难确定所有drawable
对象通用的功能,以及rectangle
,ball
等特定的功能。可以在drawable
内声明适用于所有drawable
对象的属性和方法,但是任何仅适用于特定类型drawable
的属性和方法(例如rectangle
的宽度和高度)与ball
的半径)在派生类中。
在您的示例中,如果要实例化它们,则每个派生类必须实现draw
方法(因为在基类drawable
中将其声明为纯虚拟的) )。这些特定的派生实现中的每一个都可以访问派生类的特定属性。因此,rectangle::draw
方法可以访问宽度和高度,而ball::draw
方法可以访问半径。
然后,当您有指向drawable
对象(实际上是派生类的实例)的指针的集合时,只需为每个对象调用draw方法。
抱歉,这似乎过于简单了-我希望这很清楚。