不同编译器中的输出行为

Output behaviour in different compilers

本文关键字:输出 编译器      更新时间:2023-10-16
#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++ 和代码板上生成输出HelloHello。但是当我在 Code::Blocks 上运行时,它会给出错误remove the reduntant Y::

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

在每个类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。

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
If i replace statement 1 and 2 withh Y(); , the program produces the output in all 3. Why so?

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

但是,让我们看一下变体"语句 1"。代码

int main ()
{
    X a;
}

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