不同编译器中的输出行为

时间:2013-08-30 12:28:11

标签: c++

#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
}

上述程序在Dev c ++和codepad上生成输出HelloHello。但是当我在Code :: Blocks上运行时,它会给出错误remove the reduntant Y::

如果我用Y();替换语句1和2,程序将在所有3中生成输出。为什么会这样?

3 个答案:

答案 0 :(得分:4)

在每个班级X中,X可用于引用该班级。例如,这允许

struct X {
  struct Y {
    static int f();
  };
};
int X::Y::f() {
  Y y;
  return 0;
}
int main() {
  return X::Y::f();
}

即使Y 出现,也不在X::Y::f的定义范围内。

标准指定的方式已发生变化。在最初的C ++标准中,Y被视为::X::Y的成员,意味着::X::Y。这种解释使得无法引用构造函数,因为X::X始终是一种类型。因此,在第一个TC中,标准被更改为使X::X引用类型的构造函数(在大多数情况下)。

你的一个编译器实现了原始的C ++规则,另一个编译器实现了新的规则。

根据原始规则,Y::Y();只是极好的。你正在构建一个类型。该类型具有可访问的构造函数,因此没有问题。

根据较新的规则,Y::Y();是一个错误。您正在调用构造函数,并且不允许您显式调用构造函数。

对于那些感兴趣的人,这是核心语言问题147。

答案 1 :(得分:0)

Y::Y();在C ++中是错误的。即使是Dev C ++也不应该允许它。

如果您要调用类Y的构造函数,则只需创建类型为Y的对象,例如

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

答案 2 :(得分:0)

If i replace statement 1 and 2 withh Y(); , the program produces the output in all 3. Why so?

通过调用函数Y::Y()生成输出。您可以在类X的实例的构造函数中执行此操作,也可以直接调用该函数。

但是让我们看一下变体“Statement 1”。代码

int main ()
{
    X a;
}

创建一个未使用的变量。编译器可能会优化它。在这种情况下,不会调用构造函数。这取决于编译器和使用的实际选项。当你直接调用函数Y :: Y()时,它无法被优化掉,你总是得到输出。