事实证明,我原本想要的东西可能不可能不涉及C ++ 11我想稍微改变一下要求并问你是否可以实现。
基本上我想在一个类继承自“interface”时检查编译时间。通过接口我的意思是仅使用纯虚方法的类。 我想做以下代码:
template <typename T>
class Impl : public T {
public:
STATIC_ASSERT_INTERFACE(T);
};
这里的行为是,如果T只有纯虚方法,那么它将编译,如果其中一个方法没有失败。
有人能想到这样的事吗?
答案 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
。这就是为什么我说它需要开发人员的一些纪律。
尽管如此,我看不出这是多么有用。我从来没有觉得我需要这种编译时检查。