声明类实例的两种方式的不同之处

difference in two ways of declaring a class instance

本文关键字:两种 实例 声明 方式      更新时间:2023-10-16

假设我们有一个没有默认构造函数的类:

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,也不会发生关于 x 的警告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' 的原型,它不带任何参数并返回一个 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++常见问题解答条目应该会有所帮助。

现在

Foo *x = new Foo;  //  error: no matching function for call to 'Foo::Foo()

new Foo调用默认构造函数,而您没有构造函数,这是错误的原因。如果类提供构造函数,则编译器不提供默认构造函数。

Foo x();不是

Foo类型的默认构造对象,而是一个函数声明:一个名为x的函数,不带任何参数并返回Foo。谷歌搜索"最令人烦恼的解析"。

Foo类型的默认构造对象将简单地Foo x;