我对问题标题不满意,但我无法很好地描述它。为了简洁起见,我将实现放在类声明中。
我有这样一个类:
class VisibleObject {
public:
void draw(sf::RenderWindow& rw) {
rw.draw(*shape.get());
}
virtual void setSize(sf::Vector2f) = 0;
protected:
std::shared_ptr<sf::Shape> shape;
}
sf::Shape
是一个抽象类。然后我有一个像这样的派生类:
class Brick : VisibleObject {
Brick() {
shape.reset(new sf::RectangleShape());
}
void setSize(sf::Vector2f newSize) {
std::dynamic_pointer_cast<sf::RectangleShape>(shapes).get()->setSize(newSize);
}
}
sf::RectangleShape()
是继承自sf::Shape
的具体类,并为其定义了setSize()
,不是 sf::Shape
,这就是我需要转换的原因。
当然,我需要做一些错误处理,以防动态转换失败并返回一个空的 shared_ptr。
我这样做是因为我希望能够只定义一次 draw
方法,因为在这个简单的游戏中,每个对象都将以这种方式绘制其成员。最初我把形状留在了基类之外,例如Brick 将拥有自己的私有(private) sf::RectangleShape
,可以在堆栈上实例化;这很干净,但是必须为每种对象类型重写 draw 方法。
这行得通,但使用起来更难看,并且引入了堆分配。我还有 shared_ptr
开销(我会使用 unique_ptr
,但我需要动态转换)。
这是做我想做的事情的最合适的方式吗?
最佳答案
将接口(interface)保留为接口(interface)可能更可取,而不是开始强制实现细节。所以只需要一个像这样的空基类:
class VisibleObject
{
public:
~VisibleObject() {}
virtual void draw(sf::RenderWindow & window) = 0;
virtual void setSize(sf::Vector2f const & size) = 0;
};
您可以将形状存储粘贴到实现此接口(interface)的具体类中。
此外,Shape
应该提供一个虚拟调整大小的方法:
class Shape
{
public:
virtual ~Shape() {}
virtual void resize(sf::Vector2f const & size) = 0;
};
现在您可以创建一个 VisibleShapeObject
作为中间基类:
class VisibleShapeObject : public VisibleObject
{
public:
virtual void draw(sf::RenderWindow & window) override final
{
window.draw(*shape_);
}
virtual void setSize(sf::Vector2f const & size) override final
{
shape_->resize(size);
}
protected:
std::shared_ptr<Shape> shape_; // or unique_ptr<Shape>
};
关于c++ - 在抽象基类中使用抽象类成员的最佳方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21358269/