声明类实例的两种方式的区别
假设我们有一个没有默认构造函数的类:
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
尚未定义。呼。
Assume we have a class with no default constructor:
class Foo {
public:
Foo(int data) : _data(data) { }
int data(void) const { return _data; }
private:
int _data;
};
Why does this compile and what does it do:
Foo x();
Even though the above compiles, you can't do any of the following:
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'
I guess I'm just confused about what adding the () after the x does, and why the language allows this? Is this every allowable and/or useful? It seems that no Foo instance is allocated on the stack either, because even with -Wunused-variable, no warning occurs about the x in Foo x();
In contrast, both of the following do not compile:
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()
This seems more consistent, I don't understand what is going on with Foo x();
EDIT: Ok, figured it out. Foo x()
; is a prototype for a function 'x', which takes no parameters and returns a Foo. Since the function isn't defined anywhere, trying to use it like a Foo instance (x.data()
) or Foo pointer (x->data()
) don't work. x()->data()
doesn't work because x()
is of type Foo
, not pointer to Foo
. x().data()
compiles because x()
returns Foo
, which has a data
method, but it fails to link because the function x
has not been defined. Whew.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这不会创建 Foo 类型的对象
x
。相反,您声明了一个返回类型为Foo
的函数x
。这个 C++ FAQ 条目应该会有所帮助。
现在,
new Foo
调用默认构造函数,而您没有,这就是错误的原因。如果类提供构造函数,则编译器不会提供默认构造函数。This doesn't create object
x
of type Foo. Instead you are declaring a functionx
whose return type isFoo
.This C++ FAQ entry should be helpful.
Now,
new Foo
invokes the default constructor and you don't have one and is the reason for the error. If a class provides constructor then the default constructor is not provided by the compiler.Foo x();
不是 Foo 类型的默认构造对象,而是一个函数声明:一个名为 x 的函数,不带参数并返回 Foo。谷歌搜索“最令人烦恼的解析”。Foo 类型的默认构造对象将是
Foo x;
。Foo x();
is not a default constructed object of type Foo, but a function declaration: a function called x, taking no parameters and returning a Foo. Google for 'The most vexing parse'.A default constructed object of type Foo would be simply
Foo x;
.