【问题标题】:static casting from a base class to derived从基类到派生类的静态转换
【发布时间】:2013-01-03 11:20:56
【问题描述】:

有一些不清楚的地方我想请你注意,请检查那些代码sn-ps:

template< typename DerivedClass >
class construction_management
{
    city* this_city;
public:
    construction_management()
    {
        this_city = static_cast< city* >(this);
    }
    ~construction_management();
};

我有意删除了所有不必要的代码,请查看将“this”指针静态转换为“city”类型的构造函数,其定义如下:

class city : public construction_management< city >
{

public:

public:
    city( const string& name, const string& owner );
};

该类是故意为空的,因为我认为它可以包含的内容与此处无关。希望我无法 100% 理解这里发生的事情,g++ 4.7.2 在编译阶段不会打印警告或错误,每当我使用“this_city”指针时,我都可以访问城市的所有公共成员,对象本身看起来是一致的,因为所有变量都已正确初始化并且始终包含有效数据。

我想知道的是,如果我将 construction_management 定义为普通的非模板类,为什么这段代码不起作用?由于临时从 const 到指向 city 的非 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*'

如果 construction_management 是一个模板,为什么还要工作?这是一种 CRTP 吗?

谢谢大家。

【问题讨论】:

  • 我会说这 CRTP。您正在使用它自己的基础创建派生类的模板实例化。 AFAIK 那就是 CRTP。

标签: c++ templates inheritance crtp static-cast


【解决方案1】:

它是 CRTP,因为惰性模板实例化而工作。

行:

this_city = static_cast< city* >(this);

需要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 {...};

如果基类不是模板,它会在编译器第一次看到代码时被实例化。然后编译器运行到构造函数中,此时它不知道city 是从construction_management 派生的(或者甚至city 是什么,如果它没有被声明为不完整的类型),并且放弃。

但是,如果基类是一个模板,它会在声明继承时被实例化(无论如何,我不是这方面的专家)。此时,编译器知道city 是从construction_management&lt;city&gt; 派生的,并且一切正常。

出于同样的原因,如果将构造函数定义移动到稍后编译的文件(很可能从 .h 到 .cpp),它也可以在没有模板的情况下工作。

【讨论】:

  • 嗯,如果我将代码构造函数放在 cpp 中,则工作正常。我现在唯一的困惑是从设计和优雅的角度来看,这种代码看起来如何。我需要访问城市中一些不允许作为成员出现在 construction_management 中的元素,例如,“player_info”结构被封装在 city 中,但 construction_management 还需要该结构中包含的一些信息(也city 继承自的另一个类),这就是为什么我在基类中使用 this_city 指针。
  • 将代码放在 .cpp 文件中是非常标准的做法,尤其是当否则它将无法工作。唯一不应该这样做的时候是在编写模板时(这就是为什么构造函数代码位于代码的原始模板版本的头文件中)。
  • 我的想法是指针'this_city'的使用和那个演员,我应该看看你认为不同的解决方案,还是没有我想的那么糟糕? (我不知道为什么,但不知何故我试图避免铸造操作)。
  • @user1882090 由你决定。有些人喜欢避免这种设计。我一点也不在乎,有时它更方便(这种情况?),有时你只需要这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-27
  • 1970-01-01
  • 2012-05-24
  • 2011-03-05
  • 2017-01-08
  • 2013-11-17
相关资源
最近更新 更多