Originally by Jerry Coffin from clcm (editted formatting)
> Given a class Foo:
> class Foo
> {
> Foo() { ... }
> ~Foo() { ... }
> };
As it stands at the moment, you've made Foo::Foo (and ~Foo) private, so you can't create any objects of type Foo. Presumably that was just a slip that entered during posting though. Something like this might be more informative:
struct Foo {
Foo() { std::cout << " ctor"; } ~Foo() { std::cout << " dtor"; }
};
This allows the rest of the code to compile and gives a bit of information about when the ctor and dtor are invoked.
> What's the difference between the following four functions?
> void bar() { Foo; }
This is ill-formed. "Each declarator contains exactly one declrator-id; it names the identifier that is declared." I believe a conforming compiler is required to issue a "diagnostic" for this code (though it can choose to compile it anyway, and if so treat it more or less as it chooses). It looks like MS fails to issue a diagnostic, but interprets this in an obvious way -- as not really declaring anything, so it's basically a nop.
> void bar() { Foo(); }
I'm not _entirely_ certain but I think this is allowed, and should create a temporary object of type Foo() with default initialization.
> void bar() { Foo myFoo; }
This is definitely allowed. It defines an object named myFoo of type Foo that's default initialized.
> void bar() { Foo myFoo(); }
This is definitely allowed as well. Unfortunately, this is one that has probably thrown every C++ programmer on earth at least once (it certainly has me anyway). As the warning message you got implied, this is a function declaration. It declares a function named myFoo that takes no parameters and returns an object of type Foo.
Sections 6.8 and 8.2 of the standard give a number of similar examples -- some of which require careful reading to figure out why they're interpreted the way they are. For a couple of examples from section 8.2:
void foo(double a)
{
S x(int()); // function declaration
S y((int)a); // object declaration
}
Simplifying (quite) a bit, a pattern like this gives a function declaration:
type name(type);
where a pattern like this gives an object declaration:
type name(value);
If the parentheses are empty, the compiler treats it as an empty type specification instead of an empty value, so you end up declaring a function instead of an object.
<< Home