gpt4 book ai didi

c++ - 你能覆盖同一个类中的纯虚函数吗?

转载 作者:搜寻专家 更新时间:2023-10-31 02:10:17 24 4
gpt4 key购买 nike

我想用虚函数扩展一个抽象基类,并将函数名称保持为虚函数,但在“可能”覆盖的子函数前后运行代码。

这是一个例子:

我有一个可以绘制的东西的基类(接口(interface)):

class IDraw {
public:
virtual void do_draw(Screen *scr) = 0;
};

我想在子类中保留这个接口(interface)并能够覆盖它,例如,我有一个游戏类,它可以清洁屏幕、绘制东西,然后翻转显示缓冲区:

class Game : public IDraw {
public:
// Keep the interface
// This can be overridden by sub classes
virtual void do_draw(Screen *scr) = 0; // (1)
private:
// But override the base class so if s.b. calls
// do_draw from a IDraw pointer it executes this!
void IDraw::do_draw(Screen *scr) override; // (2)
};

// Implementation of (2)
void Game::IDraw::do_draw(Screen *scr) {
// Do stuff before like clear the screen
scr->clear();
// Call the method supplied by childs
this->do_draw(scr); // (1)
// Present the drawing
scr->present();
}

因为我在 child 提供的函数之前和之后都有代码,所以我不能简单地覆盖保持它虚拟,因为 child 必须决定是在之前还是之后调用 Game::do_draw()//(2)。

我知道我可以简单地用不同的名称调用函数 (2),但由于我需要很多类来做这种事情,所以它会以相同概念的大量名称结尾。

有什么办法可以在 C++11 中做这种事情吗?

最佳答案

I want to keep this interface in subclasses and be able to override it,

这已经自动发生了,因为您在 public 访问级别继承了它。

for example I have a class for a Game, which cleans the screen, draw stuff and than flip the display buffer ...
... Is there any way to do this sort of thing in C++11?

完全独立于任何 c++11 特性,只需为抽象函数声明编写一个实现,并添加一个额外的间接层(也称为 Template Method Pattern):

class Game : public IDraw {
public:
// Keep the interface
// This can be overridden by sub classes
void do_draw(Screen *scr) override {
OnPreDraw(scr);
OnDraw(scr);
OnPostDraw(scr);
}
protected:
virtual void OnPreDraw(Screen *scr) {
// Default implementation
scr->clear();
}
virtual void OnDraw(Screen *scr) = 0; // << Class is still abstract
virtual void OnPostDraw(Screen *scr) {
// Default implementation
scr->present();
}
};

这将允许在更细粒度的操作序列中注入(inject) Game 的任何实现,但保留基类实现的默认行为。
此外,基类仍然是抽象的,有效地强制任何派生类实现 OnDraw(),这实际上与 do_draw() 相同。

but since I need many class doing this kind of stuff it will end with plenty of names for the same concept.

没有。至于你的概念只涉及操作

 OnPreDraw(scr);
OnDraw(scr);
OnPostDraw(scr);

按照这个顺序,以后整个类的继承层次结构都不会改变。


延伸:

您也可以使用 Mixin pattern 来做到这一点类(class)1

template<typename Derived>
class AbstractIDrawImpl : public IDraw {
void do_draw(Screen *scr) override {
static_cast<Derived*>(this)->OnPreDraw(scr);
static_cast<Derived*>(this)->OnDraw(scr);
static_cast<Derived*>(this)->OnPostDraw(scr);
}

// Expects public implementations
void OnPreDraw(Screen *scr) {
// Default implementation
scr->clear();
}
// Just no default implementation for
// void OnDraw(Screen *scr) << Class is still abstract
void OnPostDraw(Screen *scr) {
// Default implementation
scr->present();
}
};

上面的 mixin 示例可以绑定(bind)到 IDraw 的任何实现,它为 OnPreDraw() 提供 public 函数,OnDraw( )OnPostDraw():

class MyGame : public AbstractIDrawImpl<MyGame> {
public:
// IDraw interface implementation
void OnPreDraw(Screen *scr) {
// Call base class implementation
AbstractIDrawImpl<MyGame>::OnPreDraw(scr);
// E.g fill my background here
}
void OnDraw(Screen *scr) {
// For each game entity call
// IDraw::do_draw(scr);
for(auto drawableEntity : drawableEntities_) {
drawableEntity->do_draw(scr);
}
}
// Skip implementation of OnPostDraw()
private:
std::vector<std::shared_ptr<IDraw>> drawableEntities_;
};

1)
Alexei Andrescou 的 Policy based design paradigm 很好地描述了这种模式。并大量使用 Microsoft's ATL .

关于c++ - 你能覆盖同一个类中的纯虚函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45553935/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com