Reputation: 351
#include <iostream>
class Y
{
public:
Y();
};
class X
{
public:
void foo() {}
friend Y::Y();
X()
{
Y::Y(); //Statement 1
}
};
Y::Y()
{
std::cout << "Hello";
}
int main()
{
X a;
Y::Y(); //Statenent 2
}
The above program produces the output HelloHello
on Dev c++ and codepad. But when i run on Code::Blocks it gives error remove the reduntant Y::
If i replace statement 1 and 2 withh Y();
, the program produces the output in all 3. Why so?
Upvotes: 1
Views: 213
Reputation: 13690
If i replace statement 1 and 2 withh Y(); , the program produces the output in all 3. Why so?
The output is produced by calling the function Y::Y()
. You do this either in the constructor of an instance of the class X or by calling the function directly.
But let's look at the variant "Statement 1". The code
int main ()
{
X a;
}
creates an unused variable. The compiler might optimize it away. In that case the constructor is not called. That's dependend on the compiler and the actual options used. When you call the function Y::Y() directly it can't be optimized away and you get always the output.
Upvotes: 0
Reputation: 6588
Y::Y();
is wrong in C++. It shouldn't be allowed even by Dev C++.
If you mean to call the constructor for class Y
you just have to create an object of type Y
, e.g.
Y my; //creates an object named my of type Y
Y my = Y(); //same as above
Y(); // creates a temporary object which is destroyed in the following line
Upvotes: 0
Reputation:
Inside every class X
, X
can be used to refer to that class. This allows, for example,
struct X {
struct Y {
static int f();
};
};
int X::Y::f() {
Y y;
return 0;
}
int main() {
return X::Y::f();
}
to work, even though Y
appears to not be in scope inside the definition of X::Y::f
.
The way the standard specifies this has changed. In the original C++ standard, Y
was simply treated as a member of ::X::Y
, and meant ::X::Y
. This interpretation made it impossible to refer to a constructor, since X::X
was always a type. As a result, in the first TC, the standard was changed to make X::X
refer to a type's constructor (in most cases).
One of your compilers implements the original C++ rules, the other the newer rules.
By the original rules, Y::Y();
is just peachy. You're constructing a type. That type has an accessible constructor, so there is no issue.
By the newer rules, Y::Y();
is an error. You're calling a constructor, and you're not allowed to explicitly call a constructor.
For those interested, this is core language issue 147.
Upvotes: 4