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

标签 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”的原型(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/

相关文章:

c++ - RapidXML 节点在 try catch block 中具有正确的值,但它在 block 外为 nullptr

c - 弹丸运动程序 : What's wrong with this program?

javascript - 不明白为什么需要return语句

c++ - 异步渲染到 Qt OpenGL 窗口

c++ - 使用 if(1 || !Foo()) 有什么理由吗?

r - 编写以最高相似度匹配列名的代码/函数

c++ - 使用/不使用 vtable 初始化对象

java - 为什么 java 中没有 Optional 的公共(public)构造函数?

c++ - 从程序集调用 C/C++ 函数 (OSX Mavericks x64)

c++ - 设置两个函数相等