繁体   English   中英

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

[英]Compile time check whether a base class is “interface”

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

上一个问题

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

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

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

任何人都可以想到这样的事情吗?

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

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

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

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

另一件事 - 这里有很多灰色区域。 如果你有一个像你建议的“界面”怎么办,但有人做过其中一个:

// 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是否安全 - 这对于更熟悉标准的人来说是一个问题。

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

但是,您仍然可以通过界面开发人员的一些纪律来获得所需的行为。 如果所有接口都派生自公共基类Interface ,则可以使用类似于此问题的技术在编译时检查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派生。 这就是为什么我说它需要开发人员的一些纪律。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM