【发布时间】:2017-03-07 10:03:53
【问题描述】:
我有 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;
}
我已经阅读了这两个有希望的链接(下),但进展不大(上):-
- operator= and functions that are not inherited in C++?
- Inheritance in curiously recurring template pattern polymorphic copy (C++)
Wiki 说要转换Derive to Base is quite impossible for CRTP,所以我觉得使用 CRTP 可能没有解决方案。
问题:
- 如何将
operator->移动到某种基类以避免代码重复?
(有无 CRTP 都可以) - 有没有使用 CRTP 的解决方案?也就是说,CRTP 不适合这份工作吗?
我是 CRTP 的新手(今天就玩一下)。如有重复请见谅。
【问题讨论】:
-
首先你需要了解object slicing。那么对于您的问题,只是在第二个示例中,派生类不是从
Base派生的。继承是一种“is-a”关系,但例如Derived1不是Base,而是Helper<Base,Derived1>。 -
@Some 程序员老兄关于“is-a”:是的,关于这个的 wiki 状态。我明白。这就像 CRTP 的直接缺点。有什么解决方法吗? ....... 关于对象切片:在这种特定情况下,我并不害怕切片(主要)。我接受我收到了一些编译器警告。 :)
-
解决方法是修改
Base类。不要发明一些Helper类。但它仍然不适用于您对b对象的初始化,因为b不是Derived1对象而是Base对象,铸造将是错误的。如果您尝试b->f1(),您将有未定义的行为(如果它甚至构建)。 -
@Some 程序员老兄 谢谢!顺便说一句,我想要
d1->f1()而不是b->f1()。我只想上调。对不起,如果我的变量名称令人困惑。 -
使
Helper<T1, T2>派生自T1- 然后Derived1等人实际上将派生自Base(间接)。不过,我不清楚Base类的目的是什么,以及为什么所有DerivedX都继承自它很重要。
标签: c++11 inheritance polymorphism crtp