fja*_*sze 1 c++ inheritance templates crtp static-cast
我有些不清楚的地方希望引起您的注意,请检查这些代码片段:
template< typename DerivedClass >
class construction_management
{
city* this_city;
public:
construction_management()
{
this_city = static_cast< city* >(this);
}
~construction_management();
};
Run Code Online (Sandbox Code Playgroud)
我故意删除了所有不必要的代码,请查看构造函数,它将“this”指针静态转换为“city”类型,其定义如下:
class city : public construction_management< city >
{
public:
public:
city( const string& name, const string& owner );
};
Run Code Online (Sandbox Code Playgroud)
该类故意为空,因为我认为它所包含的内容与此处无关。希望我无法 100% 理解这里发生的事情,g++ 4.7.2 在编译阶段不打印警告或错误,每当我使用“this_city”指针时,我都可以访问 city 的所有公共成员,对象本身看起来是一致的,因为所有变量都已正确初始化并且始终包含有效数据。
我想知道的是,如果我将 Construction_management 定义为普通的非模板类,为什么此代码不起作用?由于尝试从 const 转换为指向城市的非 const 指针,转换失败,为什么?
这是错误打印:
game.hpp: In constructor 'city_manager::construction_management::construction_management()':
game.hpp:164:41: error: invalid static_cast from type 'city_manager::construction_management* const' to type 'city_manager::city*'
Run Code Online (Sandbox Code Playgroud)
如果 Construction_management 是一个模板,为什么还要工作呢?这是一种CRTP吗?
谢谢你们。
它是 CRTP,它的工作原理是由于延迟模板实例化。
该行:
this_city = static_cast< city* >(this);
Run Code Online (Sandbox Code Playgroud)
需要this可转换为city*. city如果源自则确实有效construction_management。但是,基类必须在派生类之前有完整的声明,因此只有一种写法:
//template code may or may not be present
class construction_management {...};
//maybe more code here
class city: public construction_management {...};
Run Code Online (Sandbox Code Playgroud)
如果基类不是模板,则会在编译器第一次看到代码时对其进行实例化。然后编译器运行到构造函数,此时它不知道它city是派生自的construction_management(甚至不知道 a 是什么city,如果它没有被声明为不完整类型),然后放弃。
但是,如果基类是模板,则在声明继承时会对其进行实例化(无论如何,我不是这方面的专家)。此时,编译器知道 是city派生自construction_management<city>,并且一切正常。
出于同样的原因,如果将构造函数定义移动到稍后编译的文件(很可能从 .h 到 .cpp),它也可以在没有模板的情况下工作。
| 归档时间: |
|
| 查看次数: |
2524 次 |
| 最近记录: |