SFML RenderTarget.draw:无效类型的使用无效

问题描述 投票:1回答:1

我正在读这本书https://www.packtpub.com/game-development/sfml-game-development

在第3章第61页,我们试图在目标上绘制一个sprite,如下所示:

void Aircraft::drawCurrent(sf::RenderTarget& target,
sf::RenderStates states) const
{
    target.draw(mSprite, states);
}

github上这本书的伴随代码在这里是https://github.com/SFML/SFML-Game-Development-Book/blob/master/03_World/Source/Aircraft.cpp#L31

当我尝试编译时,它给了我这个错误:

 error: invalid use of incomplete type ‘class sf::RenderTarget’
     target.draw(sprite, states);
     ^~~~~~

我在看文档时摸不着头脑,做https://www.sfml-dev.org/documentation/2.4.2/classsf_1_1RenderTarget.php#a12417a3bcc245c41d957b29583556f39看起来是正确的事

我在这本书后面的代码是在https://github.com/ishanatmuz/SFMLSnippets/blob/chapter-3/aircraft.cpp#L11

c++ sfml incomplete-type
1个回答
1
投票

你在这里绊倒一个类型的前向声明。

  • 使用(例如)class MyTypeName {...};定义完整类型。这给它起了一个名称并定义了它的实际结构(即成员,它们的类型,大小,对齐等)。
  • 一个不完整的类型基本上只是船体,就像class MyTypeName;一样,只告诉编译器这个名称代表一个实际上是类的类型。否则,无论何时使用它都不会知道如何解释MyTypeName

如果您只使用MyTypeName类的指针或引用,则其实际结构/内容并不重要。因此,使用不完整类型(在几个SFML头中声明,因此它不必包含类的完整头)就足够了。

但是,一旦开始调用该类型的成员,您将需要完整类型,因为编译器必须知道实际类型的内存布局。仅仅知道它是一个类(或整数,字符串文字等)已经不够了。要解决此问题,您实际上包含了包含完整类型的头文件。


Why even use forward declarations then?

多种原因,最突出的原因:

  • 快点。如果编译器知道MyTypeName是一个类(例如定义指针或引用)就足够了,解析一行就足够了。它不必解析潜在的数百行,存储结构信息等,只是为了将它丢弃几行。
  • 帮助您实现循环依赖。想象一下类A有一个指向类B的对象的指针,反之亦然。你不能一个接一个地定义一个类,因为当你在B之前定义A时,编译器不会知道B是什么。
© www.soinside.com 2019 - 2024. All rights reserved.