声明类实例的两种方式的区别

时间:2011-09-15 22:38:40

标签: c++ function constructor prototype

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

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();中的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尚未定义。呼。

2 个答案:

答案 0 :(得分:3)

Foo x();

这不会创建Foo类型的对象x。相反,您要声明一个函数x,其返回类型为Foo

C++ FAQ条目应该会有所帮助。

现在,

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

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

答案 1 :(得分:1)

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

Foo类型的默认构造对象只是Foo x;