C++11 CRTP避免代码重复:can';t赋值基数=由值导出
我有C++11 CRTP避免代码重复:can';t赋值基数=由值导出,c++11,inheritance,polymorphism,crtp,C++11,Inheritance,Polymorphism,Crtp,我有Base、Derived1、Derived2等课程。 它是可编译的(见下文) 编辑:我相信是这样,我认为这与问题无关 然后,我希望操作符->()位于基中,这样我就不必在所有DerivedX类中实现 这是我迄今为止的尝试,使用CRTP。它在#处不可编译:- class Base{ }; template<class T1,class T2>class Helper{ public: T2* operator->() { return static_cast<T
Base
、Derived1
、Derived2
等课程。它是可编译的(见下文) 编辑:我相信是这样,我认为这与问题无关 然后,我希望
操作符->()
位于基中,这样我就不必在所有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;
}
类基{};
模板类助手{
public:T2*运算符->(){返回静态_cast(this);}
};
类Derived1:公共助手{
public:void f1(){}
};
类Derived2:公共助手{};
类Derived3:公共助手{};
int main(){
衍生1 d1;d1->f1();
基准b=d1//#
衍生3 d3;
Derived2 d2=d3;
}
我已经阅读了这两个有希望的链接(见下文),但进展甚微(见上文):-
Wiki声明了这一点,所以我觉得可能没有使用CRTP的解决方案
问题:
- 如何将
运算符->
移动到某种基类以避免代码重复?
(带或不带CRTP都可以)
- 有没有使用CRTP的解决方案?换句话说,CRTP是否不适合此工作
我是CRTP的新手(今天就玩吧)。抱歉,如果它重复了。将对象的切片放在一边,如果将助手定义为:
template<class T1, class T2>
class Helper: public T1 {
public:
T2* operator->() {
return static_cast<T2*>(this);
}
};
不用说,现在Base b=d1
可以工作,因为Derived1
直接继承自Base
首先需要了解的是。那么对于您的问题,在第二个示例中,派生类不是从Base
派生的。继承是一种“is-a”关系,但例如,Derived1
不是Base
,而是Helper
@Some程序员关于“is-a”的问题:是的,wiki对此表示关注。我理解。这就像CRTP的一个直接缺点。有什么解决办法吗。。。。。。。关于对象切片:在这个特定的情况下,我不害怕切片(主要)。我承认我得到了一些警告。:)解决方法是修改Base
类。不要发明一些助手类。但是它仍然不能与b
对象的初始化一起工作,因为b
不是Derived1
对象,而是Base
对象,所以转换将是错误的。如果你尝试b->f1()
,你将有未定义的行为(如果它甚至生成)。@一些程序员伙计,谢谢!顺便说一下,我想要的是d1->f1()
而不是b->f1()
。我只想要上抛。抱歉,如果我的变量名令人困惑。请将Helper
派生自T1
-然后Derived1
等实际上将派生自Base
(间接)。不过,我不清楚Base
类的目的是什么,以及为什么所有DerivedX
都继承自它很重要。这需要时间来消化,但我坚信这是一个正确的解决方案。这种CRTP方法是否有任何特定的技术术语。。。看起来很酷,为什么很难消化?您需要一个从第一个模板参数继承的中间类模板,并使用第二个模板参数添加crtp内容。你只是忘了从第一步走到最后。T1
的目的是什么?在你的例子中是没有用过的,对吗?同意,我只是觉得头晕。XD@javaLover啊哈。这是常有的事。不管怎样,这个习语被称为mixin或继承自上。你把它和crtp弄混了,正如答案中提到的。哇,谢谢。我刚刚找到了自己的。
template<class T1, class T2>
class Helper: public T1 {
public:
T2* operator->() {
return static_cast<T2*>(this);
}
};
class Derived1: public Helper<Base, Derived1>;