c++ - 在抽象基类中使用抽象类成员的最佳方式?

标签 c++ c++11

我对问题标题不满意,但我无法很好地描述它。为了简洁起见,我将实现放在类声明中。

我有这样一个类:

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/

相关文章:

c++ - 如何在方法中获取 int 数组(方法参数)的长度?

c++ - 错误 : call of overloaded distance is ambiguous

c++ - 使用 [] 运算符从指向 std::array<T, N> 的指针获取类型?

c++ - makefile 以及针对 Linux 程序和 C++ 使用 eclipse

c++ - 改变 C++ 类构造函数参数的数量

c++ - 我无法在 qt 中向可执行文件添加图标

c++ - 在没有事件异常的情况下终止调用(多线程合并排序)

c++ - 用 range-v3 替换数据

c++ - C++中的15种类型分类是什么?

java - Android XML 等效于 C+ +'s "使用命名空间...”?