开发者

difference in two ways of declaring a class instance

开发者 https://www.devze.com 2023-04-05 00:42 出处:网络
Assume we have a class with no default constructor: class Foo { public: Foo(int data) : _data(data) { }

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;.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号