我想记录来自基类B和派生类C的消息,对于哪个类记录了消息是不同的:
#include "iostream"
class Logger {
public:
Logger(std::string name) : name_(name) {}
void log(std::string msg) { std::cout << name_ << ": " << msg << std::endl; }
private:
std::string name_;
};
class B : public Logger {
public:
B() : Logger("Class B" ) {}
void doSomethingInB() {
log("B doing something");
}
};
class C : public B, public Logger {
public:
C() : Logger("Class C" ) {}
void doSomethingInC() {
log("C doing something");
}
};
int main() {
B* b = new B();
C* c = new C();
b->doSomethingInB(); // I want this to output: Class B: B doing something
c->doSomethingInC();
c->doSomethingInB(); // I also want this to output: Class B: B doing something
return 0;
}我得到的错误“在‘C’中由于默认启用歧义而无法访问直接基‘Logger’,这是不言自明的。
我能实现什么不同的模型来完成这个任务呢?
发布于 2014-03-13 15:12:17
您可以使用虚拟继承,如inheritance的答案中所示,但这只会使C实例中只有一个C对象,其副作用是日志将无法输出正确的名称(您还在这个答案的注释中发现了这个问题)。
作文
一种解决方案是使用组合而不是继承:
class B
{
private:
Logger log;
// ...
};可能是最简单的解决办法。你可以看到一个live example here。
继承
另一种解决方案是通过使用CRTP使基类有所不同。这就是:
template<typename T>
class LoggerImp : public Logger
{
public:
LoggerImp(const std::string& n) : Logger(n) {}
};
class B : private LoggerImp<B>
{
private:
typedef LoggerImp<B> LL;
public:
B() : LoggerImp<B>("Class B" ) {}
void doSomethingInB()
{
LL::log("B doing something");
}
};
class C : public B, private LoggerImp<C>
{
private:
typedef LoggerImp<C> LL;
public:
C() : LoggerImp<C>("Class C" ) {}
void doSomethingInC()
{
LL::log("C doing something");
}
};一些注意事项:
B或C有用,而对这些对象的所有者没有用处。Logger类成为CRTP。发布于 2014-03-13 14:54:11
编辑:响应c->doSomethingInB();需要打印Class B: B doing something的要求,考虑组合而不是继承,因为您需要B作为自己的子类,它的记录器实际上与C的不一样(除非这里有更多的需求)。示例:
class Logger {
public:
Logger(std::string name) : name_(name) {}
void log(std::string msg) { std::cout << name_ << ": " << msg << std::endl; }
private:
std::string name_;
};
class B {
public:
B() : logger_("Class B" ) {}
void doSomethingInB() {
logger_.log("B doing something");
}
private:
Logger logger_;
};
class C : public B {
public:
C() : logger_("Class C" ) {}
void doSomethingInC() {
logger_.log("C doing something");
}
private:
Logger logger_;
};https://stackoverflow.com/questions/22382351
复制相似问题