在使用CRTP时,我遇到了一个对象切片问题。下面的模拟说明了我的问题。
#include <memory>
class CrtpGenr
{
};
template<class t_object>
class CrtpBase : public CrtpGenr
{
public:
static
auto create() -> std::unique_ptr<t_object> {
return(std::unique_ptr<t_object>(new t_object));
}
void funct1(){}
};
class CrtpDirv1 : public CrtpBase<CrtpDirv1>
{
public:
void funct2(){}
};
class CrtpDirv2 : public CrtpBase<CrtpDirv2>
{
public:
void funct2(){}
};
int main()
{
/*
// This works
std::unique_ptr<CrtpDirv1> crtp_obj = CrtpDirv1::create();
crtp_obj->funct1();
crtp_obj->funct2();
*/
std::unique_ptr<CrtpGenr> crtp_obj1 = static_cast<std::unique_ptr<CrtpGenr>>(CrtpDirv1::create());
std::unique_ptr<CrtpGenr> crtp_obj2 = static_cast<std::unique_ptr<CrtpGenr>>(CrtpDirv2::create());
crtp_obj1->funct1();
crtp_obj1->funct2();
return 0;
}编译上述代码将导致以下错误:
main.cpp: In function 'int main()':
main.cpp:47:16: error: 'class CrtpGenr' has no member named 'funct1'
crtp_obj1->funct1();
^
main.cpp:48:16: error: 'class CrtpGenr' has no member named 'funct2'
crtp_obj1->funct2();我希望能够将CrtpDirv1和CrtpDirv2类转换为CrtpGenr。这样我就可以定义一个类型为CrtpGenr的容器来保存CrtpDirv1或CrtpDirv2的对象。我做错了什么?
发布于 2016-03-30 06:37:17
*crtp_obj1是CrtpGenr类型--正如您在第48行中所声称的那样。事实上,这是正确的,因为这一切都来自于CrtpGenr。因此,static_casts编译。
但你继承的东西倒过来了,我。看看CrtpGenr的定义
class CrtpGenr
{
};它没有任何方法。您为什么期望编译器允许您尝试在该对象上调用一个?!
如果您进行强制转换,以便可以将某些公共基类型的对象放入容器(例如‘`std::list'),那么您可以这样做,但是当您想要调用该对象上的特定方法时,您需要通过将该指针转换回您创建的类型来告诉编译器它到底是哪种对象。
您可能希望更深入地研究继承和多态性。例如,CrtpGenr类可能具有派生类实现的虚拟方法funct1()。
https://stackoverflow.com/questions/36301016
复制相似问题