假设我们有一个没有默认构造函数的类:
class Foo {
public:
Foo(int data) : _data(data) { }
int data(void) const { return _data; }
private:
int _data;
};
为什么会编译以及它有什么作用:
Foo x();
即使上面的代码可以编译,您也不能执行以下任何操作:
x.data(); // doesn't compile: request for member 'data' in 'x', which is of non-class type 'Foo()'
x->data(); // doesn't compile: request for member 'data' in 'x', which is of non-class type 'Foo()'
x().data(); // compiles!!! but linking fails with: undefined reference to `x()'
x()->data();// doesn't compile: base operand of '->' has non-pointer type 'Foo'
我想我只是对在 x 之后添加 () 的作用感到困惑,以及为什么语言允许这样做?这是允许的和/或有用的吗?似乎堆栈上也没有分配 Foo 实例,因为即使使用 -Wunused-variable,也不会出现有关 Foo x();
相比之下,以下两个都不能编译:
Foo *x = new Foo; // error: no matching function for call to 'Foo::Foo()
Foo *y = new Foo();// error: no matching function for call to 'Foo::Foo()
这看起来更一致,我不明白 Foo x(); 发生了什么事
编辑:好的,明白了。 Foo x()
;是函数“x”的原型(prototype),它不带参数并返回 Foo。由于该函数没有在任何地方定义,因此尝试像 Foo 实例 (x.data()
) 或 Foo 指针 (x->data()
) 一样使用它不工作。 x()->data()
不起作用,因为 x()
的类型为 Foo
,而不是指向 Foo< 的指针
。 x().data()
编译是因为 x()
返回 Foo
,它有一个 data
方法,但是它无法链接,因为函数 x
尚未定义。哇哦。
最佳答案
Foo x();
这不会创建 Foo 类型的对象x
。相反,您声明了一个返回类型为 Foo
的函数 x
。
这个C++ FAQ输入应该会有帮助。
现在,
Foo *x = new Foo; // error: no matching function for call to 'Foo::Foo()
new Foo
调用默认构造函数,而您没有,这就是错误的原因。如果类提供构造函数,则编译器不会提供默认构造函数。
关于c++ - 声明类实例的两种方式的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7438260/