我想知道的是:
struct GenericBase{
};
struct MyObject : public GenericBase{
virtual void method() = 0;
};
struct MyAlias : public MyObject{
//supposed to have exactly the same layout as MyObject (?)
};
struct MyImpl : public MyObject{
virtual void method() { cout << "method implementation \n"; }
//note that MyImpl inherit MyObject, but we cast it to MyAlias
};
void test_alias(){
MyImpl m;
GenericBase* ptr = &m;
MyAlias* new_ptr = static_cast<MyAlias*>(ptr); //here is the cast
new_ptr->method();
}
修改
我不能使用RTTI,也不能使用模板
答案 0 :(得分:4)
答案:这不便携。
struct MyAlias : public MyObject{
//supposed to have exactly the same layout as MyObject (?)
};
此注释错误:MyAlias的大小取决于实现,并且未由标准指定(例如,它取决于目标体系结构的对齐要求:编译器可能在派生对象中添加填充位,或者关于如何实施方法调度等。)
答案 1 :(得分:1)
此代码段是否可移植?
不,这不便携。 @quantdev answer {/ 3}中所述的推理。
我要做的是省略GenericBase
和运行时多态性(virtual
)的使用:
template<typename Derived>
class MyObject {
public:
MyObject() : theRealInstance(static_cast<Derived*>(this)) {
// Check the available interface as soon an instance is created
void (Derived::*op1)(void) = &Derived::methodImpl;
(void)op1;
}
void method() {
theRealInstance->methodImpl();
}
private:
Derived* theRealInstance;
};
struct MyImpl : public MyObject<MyImpl> {
void methodImpl() { std::cout << "method implementation" << std::endl; }
};
struct MyWrongImpl : public MyObject<MyWrongImpl> {
};
void test_alias(){
MyImpl m;
m.method();
// Uncomment to see the compile time error
// MyWrongImpl w;
// w.method();
}
选中 working sample 。
你甚至可以要求method()
实现一个纯粹的抽象界面,但一般来说没有必要
struct GenericBase {
virtual void method() = 0;
};
template<typename Derived>
class MyObject : public GenericBase {
public:
virtual void method() {
theRealInstance->methodImpl();
}
// Rest as above
};
您可以在此GitHub存储库中找到有关此主题以及如何进行静态接口检查的更多信息:StaticInterfaces。