【发布时间】:2017-03-15 22:53:30
【问题描述】:
我有一个管理配置文件SettingsController 的类,它允许注册SettingsClient(一个纯虚函数,没有成员)。当相关配置条目发生更改时,SettingsClient 将收到通知,以便刷新。
现在我有一个RepositoryBase,它需要一些配置条目,因此继承SettingsClient并在SettingsController注册和一个具体的存储库ConcreteRepository,它也需要一些配置条目并继承客户端并在控制器上注册.
ConcreteRepository 继承 RepositoryBase 并且都继承 SettingsClient 以便能够在控制器上注册(在 Java 中,ConcreteRepository 将 extend RepositoryBase 并且两者都将 implement SettingsClient) .
我的问题是:编译器警告我不要这样做,因为它是模棱两可的。遗憾的是,虚拟继承在这里对我没有帮助,因为它会覆盖 ConcreteRepository 或 RepositoryBase 的已实现功能,因此禁用这两个类之一的刷新功能。
有没有办法实现这种继承-观察者-组合?我认为这可能是一个设计缺陷,RepositoryBase 需要成为ConcreteRepository(?) 的成员
这里有一些代码给出一个概述:
#include <vector>
#include <iostream>
class SettingsClient {
public:
virtual void reloadSettings() = 0;
};
class SettingsController {
void notify(){
for(SettingsClient* client : clients){
client->reloadSettings(); // error! reloadSettings() of RepositoryBase or ConcreteRepository?
}
}
void registerClient(SettingsClient *client) {
clients.push_back(client);
}
std::vector<SettingsClient*> clients;
};
class RepositoryBase : private SettingsClient {
// ...
virtual void reloadSettings() {
std::cout << "Reloading Base!" << "\n";
}
// ...
};
class ConcreteRepository : private SettingsClient, private RepositoryBase {
// ...
virtual void reloadSettings() {
std::cout << "Reloading ConcreteRepository!" << "\n";
}
// ...
};
【问题讨论】:
-
公有继承,所以多态性起作用,SettingsClient 需要一个虚拟析构函数,ConcreteRepository 不需要也继承 SettingsClient,因为它已经是通过 RepositoryBase 的一个,如果需要,可以从 ConcreteBase 显式调用 RepositoryBase 的 reloadSettings。 C++ 中没有默认调用多个基类覆盖成员的机制。
标签: c++ inheritance observer-pattern