C++中使用括号实例化类对象时为何会创建函数指针而非对象
为什么
Foo foo();会被解析为函数声明而非对象实例化? 你碰到的是C里大名鼎鼎的最令人头疼的解析(Most Vexing Parse)——这是编译器处理歧义语法时的一个默认规则,坑过不少刚开始学C的开发者。
具体解析逻辑
当你写下Foo foo();时,编译器会按照C++的语法优先级,把它解析成一个函数声明:
- 函数名是
foo - 返回值类型是
Foo - 函数不接收任何参数
这就导致后续的foo.qux(4)报错——此时foo是一个类型为Foo (*)()的函数指针,根本不是Foo类的实例,自然没法用.运算符调用成员函数。
正确的对象实例化方式
想要默认构造Foo对象,有两种可靠的写法:
- 直接省略括号:
Foo foo;,这是最常用的默认构造写法 - 用C++11引入的统一初始化语法(避免歧义):
Foo foo{};,这种写法在任何场景下都不会被解析成函数声明
为什么会有这个规则?
这个反直觉的规则其实是为了兼容C语言的语法——当编译器遇到既可以被解析为对象初始化、又可以被解析为函数声明的代码时,会优先选择函数声明的解析方式。
内容的提问来源于stack exchange,提问作者roi_saumon
相关产品推荐
相关产品推荐

