在抽象类A中,可以创建一个抽象类A类型的静态字段

时间:2016-12-07 10:39:21

标签: c++

在下面的示例中,请注意作为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 但事实证明,它在抽象类的情况下不起作用。

3 个答案:

答案 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;