代码之家  ›  专栏  ›  技术社区  ›  Priyanka Mishra

联合内部的奇怪行为类对象

  •  4
  • Priyanka Mishra  · 技术社区  · 15 年前

    嗨,我想知道以下代码的原因

    void main()
    {
      class test
      {
        public:
          test(){}
          int k;
      };
    
      class test1
      {
        public:
          test1(){}
          int k;
      };
    
      union Test
      {
        test t1;
        test1 t2;   
      };
    }
    

    对于上述代码,它给出错误“ 错误C2620:联合“测试”:成员“T1”具有用户定义的构造函数或重要的默认构造函数

    class test
    {
      public:
      //test(){}
      int k;
    };
    
    class test1
    {
      public:
      //test()1{}; 
      int k;
    };
    
    union Test
    {
      test t1;
      test1 t2; 
    };
    

    以上均无误。

    我想知道原因。

    提前谢谢。:)

    3 回复  |  直到 12 年前
        1
  •  15
  •   Gregory Pakosz    15 年前

    根据C++标准(第9章5.1节,引用其他答案):

    联合可以具有成员函数(包括构造函数和析构函数),但不能具有虚拟函数。工会不得有基层。工会不得用作基层。具有非平凡构造函数、非平凡复制构造函数、非平凡析构函数或非平凡复制赋值运算符的类的对象不能是联合的成员,也不能是此类对象的数组。如果联合包含静态数据成员或引用类型的成员,则程序格式错误。

    我第一次链接到 Wikipedia article about POD types 哪些状态:

    C++中的POD类型定义为标量类型或POD类。pod类没有用户定义的复制分配运算符,没有用户定义的析构函数,也没有本身不是pod的非静态数据成员。此外,pod类必须是一个聚合,这意味着它没有用户声明的构造函数,没有私有或受保护的非静态数据,没有基,也没有虚拟函数。该标准包括关于POD如何在C++中运行的语句。

    在某些上下文中,C++只允许使用POD类型。 例如,C++中的联合不能包含具有虚函数的类或非平凡构造函数或析构函数。 . 由于编译器无法知道应该为联合调用哪个构造函数或析构函数,因此施加了此限制。

    第二段的第一句话可能会让你认为C++只允许POD类型成为联盟的一部分。事实并非如此,因为它允许具有私有成员的类成为联合的一部分:

    #include <iostream>
    using namespace std;
    
    class test1
    {
      int i;
    };
    
    class test2
    {
      int i;
    };
    
    union test
    {
      test1 t1;
      test2 t2;
    };
    
    int main()
    {
      cout << __is_pod(test1) << endl;
      cout << __is_pod(test2) << endl;
      cout << __is_pod(test) << endl;
    
      return 0;
    }
    

    上面用msvc++编译的程序打印出来:

    0
    0
    1
    
        2
  •  5
  •   Charles Salvia    15 年前

    C++标准对可以放置在一个联合内部的数据类型提出了某些限制。在9.5.1中,标准为:

    A的对象 用一个非平凡的构造函数, 一个重要的复制构造函数,一个 非平凡析构函数,或 非平凡的复制分配运算符 不能是工会成员,也不能 此类对象的数组。如果工会 包含静态数据成员,或 引用类型的成员 程序格式错误。

    所以您的程序不能工作,因为您显式地定义了一个构造函数,因此您的对象违反了重要的构造函数限制。

        3
  •  2
  •   anon    15 年前

    在C++中,联合可能不包含具有(非平凡)构造函数或析构函数的类。这是因为编译器无法告诉创建或销毁联合实例时要使用哪个构造函数或析构函数。

    推荐文章