编译时检查基类是否为"接口"
Compile time check whether a base class is "interface"
事实证明,如果没有涉及C++11,我最初想要的可能是不可能的,我想稍微改变一下需求,并询问您是否可以实现这一点。
上一个问题
基本上,我想在编译时检查一个类是否从"接口"继承。我所说的接口是指只使用纯虚拟方法的类。我想做以下代码:
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);
我几乎百分之百肯定你无法阻止别人这么做。
尽管我不确定自己是否同意这种做事方式,但你可以确保没有成员变量。制作一个空类,然后执行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
派生。这就是为什么我说它需要开发人员的一些纪律。
尽管如此,我看不出这会有什么用处。我从来没有觉得我需要这种编译时检查。
- "IDispatch::GetTypeInfo()"接口是否正常
- Djinni 记录是否包含可选的接口字段
- 抽象类/接口中的空方法是否被认为是一种好的做法?
- 是否可以从C 调用FORTRAN接口
- C 是否具有接口类概念,如果它在那里,那么它与Java接口类别有何不同
- C++ 接口类继承自具体类是否合理
- 在C 11或更高版本中,是否可以通过Lambda来实现单方法纯Virtual C 接口
- Blas 和 Lapack 库是否有本机 C++(不是 C)接口?
- 是否有任何挂钩接口在编译时间内更换功能
- OmNET++动态检查NED模块是否实现了接口
- 是否在对象中创建临时接口
- 是否有一个更适合键值数据结构的QABSTRACTITEMMODEL类型类/接口
- 我是否必须在C 接口的OPENCV C包装器中自由分配的内存
- 是否可以将C++接口与Objective-C一起使用
- 是否覆盖Direct3D接口
- 自lambdas进入C++以来,“回调”接口是否已过时
- 是否可以检查接口是否在 pcap 中激活
- 导入"RegExp.tlb" C++ COM 接口是否在进程之间隐式共享内存?
- QT检查接口是否真实
- C++库中的文件打开接口是否应该在Windows上使用UTF-8