Erik said:
Erik Wikström wrote:
On 2008-10-19 06:39, Sam wrote:
Kai-Uwe Bux writes:
Vijay Meena wrote:
Hi,
This code is of no use. But I am just curious to know about
what happening here.
#include <iostream>
using namespace std;
class Foo {
private:
int i;
public:
Foo() {
cout << "Foo::Foo()" << endl;
Foo(i);
}
Foo(int i) : i(i) {
cout << "Foo::Foo(int)" << endl;
}
~Foo() {
cout << "Foo::~Foo()" << endl;
}
};
int main(int argc, char *argv[])
{
Foo();
}
I am getting infinite call to "Foo::Foo()". Program is not
even executing "Foo::Foo(int)".
Hm, I am flabbergasted. The following _does_ the expected:
Foo() {
cout << "Foo::Foo()" << endl;
Foo( this->i );
}
and prints:
Foo::Foo()
Foo::Foo(int)
Foo::~Foo()
Foo::~Foo()
I have no idea, what difference the "this->" should make.
BTW: initializing i in the constructor does not help (although
the program might have UB without doing so).
This looks like a bug in gcc (4.3.0, in my case).
MSVC behaves the same way.
I think that CockneyWinker has the solution in his posting:
The problem is that the line Foo(i) is equivalent to Foo i, ...
This seems to go against [5.2.3/1], but only if the line could
not be parsed as a declaration. By [6.8/1] it seems that is can.
Best
Kai-Uwe Bux
Yes, It seems so. When I change Foo(i) to Foo((int)i) or Foo(2)
then it behaves properly. But why does it need _extra_ typecast ?
can't it see that _i_ is declared as an int ? I am sorry, I don't
have much experience with C++. I still couldn't understand that
how Foo(i) is equal to *Foo i* ?
Since you are allowed to declare a local variable with the same
name as a member the compiler interprets this as such. Why it is
allowed I don't know, but someone must have thought that it was
good for something.
Inner scopes are allowed to declare names also present in outer
scopes. Class members are no different from other scopes.
The fact that a set of parenthesis are allowed is just because
*sometimes* they are needed. There are just no rules about not using
them when not needed.
Also, if Foo(i) were to work as "expected", it would also create a
temporary Foo inside the constructor. This is also pretty useless (and
strictly UB, as the outer i is still uninitialized).
I guess that the OP really wants a "delegating constructor" which will
be available in the next standard, C++0x. A constructor will be able
to call another constructor of the same class, in its initializer
list:
Foo() : Foo(1)
{ }
will set i to 1. Foo(i) will till be bad though!
Bo Persson