"(GameState *) new PlayingState()"做什么?

What does "(GameState *) new PlayingState()" do?

本文关键字:什么 new GameState PlayingState      更新时间:2023-10-16

(GameState *) new PlayingState() 

对我来说没有多大意义。由于GameState*是一个指向类的指针,并且使用了new运算符,所以它表明PlayingState()是一个从另一个类"新建"的对象。我的问题出现在这篇文章的末尾,但首先是各自类别的定义:

class GameState
{
public:
virtual void onStart(StateBasedGame &game) = 0;
};
class PlayingState : public GameState, public EventSubscriber<sf::Event>
{
public:
PlayingState();
void onStart(StateBasedGame &game);
};

我的问题:

1.是在两个班之间选角吗?您可以在C++中强制转换类,就像在C中强制转换数据类型一样?我觉得C++更"正式"answers"多余"?

2.你为什么要那样做?这样的转换有什么意义,作者能达到什么目的?我猜这与构造函数有关。

3.对于new,你不应该使用这种格式吗?:

<class_type> <new_class_name> = new <class_type_name>

GameState gameState = new PlayerState;

显然这不是唯一的方法?

如果没有进一步的上下文,这至少可以说是奇怪的(我无法想象上下文中这是有意义的)。

首先,您是对的,在C++风格的代码中,您将根据情况使用static_castdynamic_cast在类之间进行强制转换。

其次,由于PlayingState继承自GameState,指向PlayingState的指针(由new PlayingState()返回)可以隐式转换为GameState*。根本不需要演员阵容。

在这种情况下,作者可以简单地使用:

GameState *gs = new PlayingState();

甚至更好,使用现代C++:

auto gs = std::make_unique<PlayingState>()

(参见std::unique_ptrstd::make_uniqueauto)

(GameState *) new PlayingState() 

创建类PlayingState的新指针,然后将其投射到类GameState。

class PlayingState : public GameState, public EventSubscriber<sf::Event> {

是一个扩展GameState和另一个类的类。来自父类型的数据结构也得到了扩展。

class GameState

在Java/C#中可以看作interface,因为只有纯虚拟方法(virtual <ret-type> <name>(<arguments>) = 0)。

虚拟方法存储在VMT(虚拟方法表)中,对任何虚拟方法的函数调用都会通过索引调用VMT中的方法。

您不能像不启动接口那样启动纯虚拟类。因此GameState gameState = new GameState无效。您还错过了GameState gameState的一个指针。

由于PlayingStateGameState的子级,因此PlayingState只能在指针中转换为GameState

要处理对象,您必须使用deletedelete gameState即可。

不要尝试freegameState,因为freeing不会调用析构函数例程。

编辑

C++还支持RTTI(运行时类型信息)。在C++中有const_castdynamic_castreinterpret_caststatic_cast

人们建议使用dynamic_cast进行父子转换的原因是,可以进行基本的运行时类型检查。这样就可以正确处理不可比较的类型,否则就会创建另一个指针地狱。

dynamic_cast,执行:

dynamic_cast<GameState *>(new PlayingState())

如果两种类型都不坚持任何关系,则可以catchbad_cast

try {
dynamic_cast<GameState *>(new PlayingState())
} catch (std::bad_cast &oops) {
// nightmare
}

PlayingStateGameState的子类。

所以强制转换是可以的。如果你有用于操作基类的代码,或者如果你需要返回基类的指针,子类通常会在它的基类中转换。

你也可以有这样的东西:

Parent *p;
if (...) {
p = new Child1();
} else {
p = new Child2();
}
//do stuff with p

但是,当将子指针转换为父指针时,不需要手动C样式转换。

我能想到的唯一有意义的例子是,如果你想调用子函数和父函数中都存在的函数,而不是virtual(在你的例子中,父函数中的所有函数都是虚拟的),那么你可以这样做:

((GameState*) new PlayingState()) -> doStuff(...)

但这是一种扭曲的方式,这也会起作用:

GameState *g = new PlayingState();
g->doStuff();

简而言之,如果没有更多的代码或上下文,我只能认为这是不必要的,也是无害的冗余。


至于强制转换运算符,C++中有几个。dynamic_cast可以用于从父母转换到孩子(甚至在同一个孩子的父母之间),并安全地检查它是否可行,但在这里它没有用处。