CRTP避免代码重复:无法分配Base =按值派生

时间:2017-03-07 10:03:54

标签: c++11 inheritance polymorphism crtp

我有课程BaseDerived1Derived2等  它是可编辑的(下图)。

class Base{  };
class Derived1 : public Base{
    public: Derived1* operator->() { return this; }
    public: void f1(){}
};
class Derived2 : public Base{
    public: Derived2* operator->() { return this; }
};
class Derived3 : public Derived2{
    public: Derived3* operator->() { return this; }
};
int main(){//test case (my objective is to make all these work)
    Derived1 d1;  d1->f1();
    Base b=d1;              //non harmful object slicing
    Derived3 d3;
    Derived2 d2=d3;
}

编辑: 我认为它是a non-harmful object slicing,我认为这与此问题无关。

然后,我希望operator->()位于Base内,所以我不必在所有DerivedX类中实现。

这是我到目前为止的尝试,使用CRTP。它在#处无法编译: -

class Base{  };
template<class T1,class T2>class Helper{
    public: T2* operator->() { return static_cast<T2*>(this); }
};
class Derived1 : public Helper<Base,Derived1>{
    public: void f1(){}
};
class Derived2 : public Helper<Base,Derived2>{    };
class Derived3 : public Helper<Derived2,Derived3>{    };
int main(){
    Derived1 d1;  d1->f1();
    Base b=d1;                    //#
    Derived3 d3;     
    Derived2 d2=d3;
}

我已经阅读了这两个有希望的链接(下面),并且进展不大(上图): -

Wiki声明投射Derive to Base is quite impossible for CRTP,所以我觉得使用CRTP可能没有解决方案。

问题:

  • 如何将基类的operator->移动到某种以避免代码重复?
    (有或没有CRTP都可以)
  • 有没有使用CRTP的解决方案?换句话说,CRTP不适合这份工作吗?

我是CRTP的新手(今天就玩它)。对不起,如果它是重复的。

1 个答案:

答案 0 :(得分:2)

抛开对象的切片,如果将助手定义为:

,那么您的示例就可以正常工作
template<class T1, class T2>
class Helper: public T1 {
public:
    T2* operator->() {
        return static_cast<T2*>(this);
    }
};

那是:

  • T1导出,就好像采用基于纯混合的方法
  • 使用T2,就像使用纯CRTP方法一样

如果您考虑Derived1的声明:

class Derived1: public Helper<Base, Derived1>;

不言而喻,现在Base b = d1;有效,Derived1直接从Base继承。