在下面的示例中,请注意作为AbstractMiddleware实例的TERMINATOR:
#include <iostream>
class AbstractMiddleware { // base class for middleware
public:
AbstractMiddleware();
virtual ~AbstractMiddleware() { }
virtual void call() = 0; // typical middleware does something and calls next one in chain
AbstractMiddleware* next;
};
static class : public AbstractMiddleware {
public:
void call() override {
std::cout << "TERMINATE" << std::endl;
}
} TERMINATOR; // dummy middleware to terminate the chain
AbstractMiddleware::AbstractMiddleware():
next(&TERMINATOR) // each middleware is terminated by default
{ }
我不喜欢TERMINATOR在AbstractMiddleware之外声明。事实上,它是唯一使用TERMINATOR的地方(目前)。理想情况下,我想将它作为静态字段AbstractMiddleware :: TERMINATOR隐藏在AbstractMiddleware中,但不知道如何。
[编辑]
事实证明,在我原来的问题中,我不够清楚。
正如StoryTeller和Dialecticus正确猜测的那样,我最初关注的是将TERMINATOR实例从公共命名空间中隐藏起来,同时保持它对AbstractMiddleware及其后代可见。
我认为将它作为静态放入AbstractMiddleware就像在这里完成的那样:https://stackoverflow.com/a/21197907/947418 但事实证明,它在抽象类的情况下不起作用。
答案 0 :(得分:1)
如果我理解正确的话。你有一个在它之外定义的类紧密耦合的构造,它会困扰你。 C ++不允许定义内部子类。那么为什么不公开指针本身以供客户端用作终结符呢?
部首:
class AbstractMiddleware { // base class for middleware
public:
AbstractMiddleware();
virtual ~AbstractMiddleware() { }
virtual void call() = 0; // typical middleware does something and calls next one in chain
AbstractMiddleware* next;
protected:
static AbstractMiddleware * const TERMINATOR;
};
来源:
static class : public AbstractMiddleware {
public:
void call() override {
std::cout << "TERMINATE" << std::endl;
}
} TERMINATOR_OBJ; // dummy middleware to terminate the chain
AbstractMiddleware * const AbstractMiddleware::TERMINATOR = &TERMINATOR_OBJ;
AbstractMiddleware::AbstractMiddleware():
next(TERMINATOR) // each middleware is terminated by default
{ }
终结者对象现在已隐藏在AbstractMiddleware
的翻译单元内。
答案 1 :(得分:1)
您可以在TERMINATOR
和构造函数定义之间的.cpp文件中的某处将#include "AbstractMiddleware.h"
代码移动到匿名(或无名)命名空间。这样,AbstractMiddleware.cpp之外的任何人都不会知道它:
#include "AbstractMiddleware.h"
namespace
{
static class : public AbstractMiddleware {
public:
void call() override {
std::cout << "TERMINATE" << std::endl;
}
} TERMINATOR; // dummy middleware to terminate the chain
}
AbstractMiddleware::AbstractMiddleware():
next(&TERMINATOR) // each middleware is terminated by default
{ }
答案 2 :(得分:1)
AbstractMiddleware是否需要严格抽象?
class AbstractMiddleware {
protected:
AbstractMiddleware();
public:
virtual ~AbstractMiddleware() { }
virtual void call() { std::cout << "TERMINATE" << std::endl; }
AbstractMiddleware* next;
private:
static AbstractMiddleware TERMINATOR;
};
AbstractMiddleware::AbstractMiddleware():
next(&TERMINATOR)
{ }
AbstractMiddleware AbstractMiddleware::TERMINATOR;