【问题标题】:Accessing a derived class members from an "interface" in C++?从 C++ 中的“接口”访问派生类成员?
【发布时间】:2018-08-09 21:58:30
【问题描述】:

我正在开发一个 UI 框架并尝试使我的代码更易于管理并使用接口(我知道它们只是类。)似乎是最好的选择。

我会给你一个我想做的例子:

在控件基类中,它将具有所有控件都具有的通用成员,例如 ID、名称和位置。我希望能够实现一个界面来管理一个按钮的文本。界面将存储和绘制文本。 现在要做到这一点,我需要重写 Draw() 函数,但是我不知道我如何转发声明。

伪代码

class ITextAble
virtual void DrawText() override Control::Draw()
{
    Control::Draw();
    GetRenderWindow()->draw(m_text);
}

class Button : public ITextAble

virtual void Draw ()
{
    m_renderWindow->draw(m_shape);
}
sf::RenderWindow * GetRenderWindow () const
{
    return m_renderWindow;
}

如果你不能说我对 C++ 编程很陌生,我不知道这是否可以在 C++ 中完成,但如果是真的,我会再次感到惊讶。

【问题讨论】:

  • 只有Draw 可以覆盖Draw。被覆盖的Draw 将不得不满足于调用DrawText

标签: c++ inheritance interface


【解决方案1】:

您最好使用一些现成的库,如 fltk、wxWidgets、QT、MFC、GTKMM 等。 您会发现创建 GUI 库是一项超级复杂的任务。

看来您不了解接口(纯虚拟类)的概念。这样的类不能有任何成员——只有纯虚方法。否则 - 这是一个抽象类。

阅读 Scott Meyers:有效的 C++

可以使用经典动态多态版本涵盖您的概念的东西:

警告!这是糟糕的设计!

更好的方法 - 根本没有 sf::RenderWindow * GetRenderWindow () const 函数。

// a pure virtual class - interface
class IControl {
IControl(const IControl&) = delete;
IControl& operator=(const IControl&) = delete;
protected:
  constexpr IControl() noexcept
  {}
protected:
  virtual sf::RenderWindow * GetRenderWindow() const = 0; 
public:
  virtual ~IControl() noexcept
  {}
}

// an abstract class
class ITextAble:public IControl {
  ITextAble(const ITextAble&) = delete;
  ITextAble& operator=(const ITextAble&) = delete;
protected:
   ITextAble(const std::string& caption):
     IControl(),
     caption_(caption)
  {} 
   void DrawText();
public:
   virtual ~ITextAble() noexcept = 0;
private:
   std::string caption_;
};

// in .cpp file

void ITextAble::DrawText()
{
  this->GetRenderWindow()->draw(caption_.data());
}

ITextAble::~ITextAble() noexcept
{}

// 
class Button :public ITextAble
{
public:
  Button(int w, int h, const char* caption) :
    ITextAble(caption),
    window_(new sf::RenderWindow(w,h) ),
  {}
  void show() {
     this->DrawText();
  }
  virtual ~Button() noexecept override
  {}
protected:
  virtual sf::RenderWindow* GetRenderWindow() const override {
    return window_;
  }
private:
  sf::RenderWindow* window_;
};

// pointer on reference
Button *btn = new Button(120, 60, "Click me");
btn->show();

【讨论】:

  • 我想了很多,我知道另一种方法是在 ITextAble 构造函数中引用控件。感谢您解释纯虚拟类概念。但我不会使用 GUI 库,因为我相信我能够管理。我知道这很难,这就是我想做的原因。感谢您的回答。
  • 抽象类不能自己实例化,但也可以有非虚函数和成员变量。
猜你喜欢
  • 2010-12-19
  • 1970-01-01
  • 2011-01-27
  • 2017-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-05
相关资源
最近更新 更多