某种类型的别名:一个空的派生类

时间:2014-06-10 18:32:29

标签: c++ inheritance types alias downcast

我想知道的是:

  • 此代码段是否可移植?
  • 如果没有,为什么?

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,也不能使用模板

2 个答案:

答案 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