我有课程Base
,Derived1
,Derived2
等
它是可编辑的(下图)。
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的新手(今天就玩它)。对不起,如果它是重复的。
答案 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
继承。