在基类中我通过id虚函数进行简单删除,但是在派生类中我还需要在删除后发出一个信号(notify)。
在基类中。以下是函数
的默认实现void Ui::GameEntityList::remove_games_by_sport_id_virt(const QString &sport_id)
{
for(QList<GameEntity*>::iterator it = m_game_list.begin();
it != m_game_list.end();)
{
GameEntity* tmp = (*it);
if(tmp->get_sport_id() == sport_id)
{
it = m_game_list.erase(it);
delete tmp;
tmp = 0;
}
else
{
++it;
}
}
}
在派生类中。覆盖
void Ui::GameWidgetList::remove_games_by_sport_id_virt(const QString &id)
{
QList<GameEntity*>::iterator it;
for(it = m_game_list.begin(); it != m_game_list.end();)
{
GameWidget* tmp = dynamic_cast<GameWidget*>(*it);
Q_ASSERT(tmp != NULL);
if(tmp->get_sport_id() == id)
{
it = m_game_list.erase(it);
emit remove_game_in_monitor(tmp->get_id(), this->get_monitor_number()); // need to emit this signal
delete tmp;
tmp = 0;
}
else
{
++it;
}
}
this->set_number_of_games(m_game_list.size()); // need to call this function
}
我无法管理避免代码重复的方法。我应该有一个空的虚拟notify()函数并在删除元素后调用它吗?这样我可以覆盖派生的notify()来完成这项工作。这是可以接受的决定吗?在基类中实现删除id是不必要的吗?
答案 0 :(得分:3)
在您的情况下,重复代码的数量并没有那么糟糕。但是,无论如何,在这种情况下,您可能希望将此功能设置为非虚拟,并将此可自定义功能移至其他虚拟功能:
class GameEntityList
{
private:
virtual void on_erase(GameWidget* w)
{
//empty
}
virtual void on_finish(GameWidget* w)
{
//empty
}
//others
};
class GameWidgetList : public GameEntityList
{
private:
virtual void on_erase(GameWidget* w)
{
remove_game_in_monitor(w->get_id(), this->get_monitor_number());
}
virtual void on_finish(GameWidget* w)
{
this->set_number_of_games(m_game_list.size());
}
//others
};
然后:
void Ui::GameEntityList::remove_games_by_sport_id_virt(const QString &id)
{
QList<GameEntity*>::iterator it;
for(it = m_game_list.begin(); it != m_game_list.end();)
{
if(tmp->get_sport_id() == id)
{
it = m_game_list.erase(it);
this->on_erase(tmp); //customizable
delete tmp;
tmp = 0;
}
else
{
++it;
}
}
this->on_finish(); //customizable
}