编译时检查基类是否为“接口”

时间:2012-03-28 07:16:07

标签: c++ compilation

事实证明,我原本想要的东西可能不可能不涉及C ++ 11我想稍微改变一下要求并问你是否可以实现。

previous question

基本上我想在一个类继承自“interface”时检查编译时间。通过接口我的意思是仅使用纯虚方法的类。 我想做以下代码:

template <typename T>
class Impl : public T {
public:
STATIC_ASSERT_INTERFACE(T);
};

这里的行为是,如果T只有纯虚方法,那么它将编译,如果其中一个方法没有失败。

有人能想到这样的事吗?

3 个答案:

答案 0 :(得分:2)

这基本上类似于 Java接口。在C ++中,不存在interface,它只是一个用于class的术语,包含所有纯虚方法和static const个数据成员。

此外,纯虚方法可能有也可能没有函数体。因此,C ++纯虚方法与Java的抽象方法不完全相同。

不幸的是,你要问的是不可能在C ++中进行模拟。

答案 1 :(得分:1)

首先,接口并不是C ++的本机概念。我确信大多数程序员都知道它们是什么,但是编译器没有,而且那是你遇到问题的地方。 C ++可以做很多事情,我打赌你可以把它变成很多不同的语言,但是如果你要编写C ++,最好用C ++方式做事。< / p>

另一件事 - 这里有很多灰色区域。如果你有一个&#34;界面&#34;像你建议的那样,但有人做了其中一个:

// Technically not a member function, but still changes the behavior of that class.
bool operator==(const Interface &left, const Interface &right);

我几乎100%确定你不能阻止某人这样做。

尽管我不确定我是否同意这种做事方式,但您可以确保没有成员变量。创建一个空类,然后执行static_assert(sizeof(InterfaceClass) == sizeof(Empty))。我不确定假设大小是0是否安全 - 对于那些更熟悉标准的人来说这是一个问题。

答案 2 :(得分:1)

你想要的不能直接完成,正如其他人已经解释过的那样。

但是,您仍然可以通过界面开发人员的一些纪律来获得您想要的行为。如果所有接口都派生自公共基类Interface,则可以使用类似于this question的技术在编译时检查Interface是否为基类。

例如:

class Interface {
    public :
        virtual ~Interface() { }
};

template <typename T>
struct IsDerivedFromInterface {
    static T t();
    static char check(const Interface&);
    static char (&check(...))[2];
    enum { valid = (sizeof(check(t())) == 1) };
};

class MyInterface : public Interface {
    public :
        virtual void foo() = 0;
};

class MyBase {
    public :
        virtual void bar() { }
};

class Foo : public MyInterface {
    public :
        virtual void foo() { }
};
BOOST_STATIC_ASSERT(IsDerivedFromInterface<Foo>::valid);    // just fine

class Bar : public MyBase {
    public :
        virtual void bar() { }
};
BOOST_STATIC_ASSERT(IsDerivedFromInterface<Bar>::valid);    // oops

当然,即使基类不是接口,基类的开发人员也可以欺骗并派生自Interface。这就是为什么我说它需要开发人员的一些纪律。

尽管如此,我看不出这是多么有用。我从来没有觉得我需要这种编译时检查。