difference in two ways of declaring a class instance
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 po开发者_如何学编程inter 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.
Foo x();
This doesn't create object x
of type Foo. Instead you are declaring a function x
whose return type is Foo
.
This C++ FAQ entry should be helpful.
Now,
Foo *x = new Foo; // error: no matching function for call to 'Foo::Foo()
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();
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;
.
精彩评论