"(GameState *) new PlayingState()"做什么?
What does "(GameState *) new PlayingState()" do?
行
(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_cast
或dynamic_cast
在类之间进行强制转换。
其次,由于PlayingState
继承自GameState
,指向PlayingState
的指针(由new PlayingState()
返回)可以隐式转换为GameState*
。根本不需要演员阵容。
在这种情况下,作者可以简单地使用:
GameState *gs = new PlayingState();
甚至更好,使用现代C++:
auto gs = std::make_unique<PlayingState>()
(参见std::unique_ptr
、std::make_unique
和auto
)
(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
的一个指针。
由于PlayingState
是GameState
的子级,因此PlayingState
只能在指针中转换为GameState
。
要处理对象,您必须使用delete
。delete gameState
即可。
不要尝试free
gameState
,因为free
ing不会调用析构函数例程。
编辑:
C++还支持RTTI
(运行时类型信息)。在C++中有const_cast
、dynamic_cast
、reinterpret_cast
和static_cast
。
人们建议使用dynamic_cast
进行父子转换的原因是,可以进行基本的运行时类型检查。这样就可以正确处理不可比较的类型,否则就会创建另一个指针地狱。
至dynamic_cast
,执行:
dynamic_cast<GameState *>(new PlayingState())
如果两种类型都不坚持任何关系,则可以catch
和bad_cast
。
try {
dynamic_cast<GameState *>(new PlayingState())
} catch (std::bad_cast &oops) {
// nightmare
}
PlayingState
是GameState
的子类。
所以强制转换是可以的。如果你有用于操作基类的代码,或者如果你需要返回基类的指针,子类通常会在它的基类中转换。
你也可以有这样的东西:
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
可以用于从父母转换到孩子(甚至在同一个孩子的父母之间),并安全地检查它是否可行,但在这里它没有用处。
- 如果我在 c++ 中以 new 的放置形式使用没有足够的内存,会发生什么情况?
- int** a = new int*[n]();这个函数有什么作用?
- "new int * **[10]"做什么?
- 有些时候,阶级必须"default copy c'tor" ?当我做"new Type[..]"时会发生什么?
- 对于没有功能的结构,"new (ptr) mystruct;"做什么?
- 使用泛型成员变量"placement new"结构/类数组的正确方法是什么?
- new和::new有什么区别
- 带"new"的指针和带"&variable"的指针有什么区别
- "a = new arr ***[num];"的含义是什么?
- 将内存分配给 2D 数组时,“new int*[rowCount];”的含义是什么?是 2D 数组,是指向数组的指针数组
- C++用法:" *(new int); "做什么?
- new _Elem[_Size]() 与 new _Elem[_Size]{} 有什么区别?
- int '*p = new int (5);' 和 'int *p = new int[5];' 有什么区别?
- (类 *对象;)和(object = new class();)之间有什么区别
- 除了使用 new 之外,什么会导致内存泄漏?(C++)
- "{}" "new int[5]{};"的目的是什么?
- 新的int()和new int []有什么区别
- "new Classname*[]"是什么意思?
- "new int(100)"做什么?
- 在混合 C/C++ 程序中协调 malloc 和 new 的"正确"方法是什么?