何时在构造函数中使用 {} ()
When to use {} () in constructors
在Game.h
中,我有一个名为Game
的类:
class Game
{
public:
Game();
void run();
private:
sf::Event e;
sf::RenderWindow app;
sf::Clock delay;
unsigned counter = 0;
Ice *ball = new Ice(app);
Players *players = new Players(app);
Collision collision;
void handleEvent();
};
然后,在Game.cpp
中,我使用:
Game::Game() : app({1000,800},"NAME")
{
}
语法
Game::Game() : app(sf::VideoMode(1000,800),"NAME")
{
}
也有效。
我的问题是:为什么在第一种情况下我可以省略sf::VideoMode
,如果我这样做,为什么我必须对视频模式参数使用{}
?在第一种情况下使用()
会导致错误。
您的Game
构造函数正在调用以下sf::RenderWindow
构造函数:
RenderWindow (VideoMode mode, const String &title, Uint32 style=Style::Default, const ContextSettings &settings=ContextSettings())
您必须向它传递一个完全构造的sf::VideoMode
对象。
您的两个示例都在sf::RenderWindow
构造函数调用中内联构造一个临时VideoMode
对象。 它们都调用以下sf::VideoMode
构造函数,只是使用不同的语法:
VideoMode (unsigned int modeWidth, unsigned int modeHeight, unsigned int modeBitsPerPixel=32)
C++11引入了一个名为"统一初始化"的新功能,它将不同上下文中使用的各种不同类型的初始化语法统一到使用大括号的单个语法中,从而大大简化了编码。 在这种情况下,列表初始化用于使用braced-init-list
初始化临时对象。正是此功能允许您{1000,800}
示例直接在函数参数中构造临时sf::VideoMode
对象,而无需显式声明其类名。
早期C++版本没有"统一初始化"。 在这些版本中,构造函数只能按名称显式调用。 这就是允许您sf::VideoMode(1000,800)
示例构造临时sf::VideoMode
对象的原因(它在 C++11 及更高版本中仍然是有效的语法)。
(1000,800)
本身C++用于构造对象的语法都无效,在任何C++版本中。
为什么在第一种情况下我可以省略
sf::VideoMode
因为app
构造函数的第一个参数被声明为已经具有类型sf::VideoMode
。
这与你可以编写long v = 1;
而不必编写long v = long{1};
或类似的东西的原因相同:编译器知道正在初始化的变量或参数的类型,并且可以检查该类型是否支持使用您指定的初始化器进行构造,即使初始化器没有相同的类型。
如果我这样做,为什么我必须使用
{}
作为视频模式参数?
因为(1000,800)
已经有了不同的更古老的含义:它的意思是"获取值1000
,丢弃它,然后800
获取值"。诚然,在这种情况下,这是没有意义的,但是没有办法重写语言,使(1000,800)
在您的情况下工作,同时合理的先前有效的代码也继续工作。
- 何时应在构造函数参数中使用 const C++?
- 何时允许编译器优化复制构造函数
- 何时调用全局对象的构造函数?
- 何时在构造函数中使用 {} ()
- 何时应删除默认的移动构造函数时令人困惑的事情
- 返回值的复制构造函数何时发生
- 何时使用复制构造函数
- 移动构造函数何时会被调用
- C++类组合 - 何时执行构造函数和析构函数
- 使用构造函数时何时必须使用"this C++?
- 何时构造函数调用中的堆栈对象
- 何时提供用户定义的复制构造函数和赋值运算符
- 在构造函数的初始化列表中初始化时,何时构造成员对象?
- 运算符在C++中何时调用'new'构造函数
- 编译器何时将默认生成的构造函数标记为 noexcept
- 编译器何时不会创建默认构造函数
- 何时调用构造函数和运算符函数
- 何时调用构造函数以及如何不调用它们
- 构造函数何时调用 const-expr
- c++静态分配对象的构造函数何时运行