代码之家  ›  专栏  ›  技术社区  ›  noisy

默认构造函数,为什么我的类似乎有三个?当编译器将类视为结构时?

  •  3
  • noisy  · 技术社区  · 15 年前

    我一直以为只有两个 默认值

    但今天我写了这样的东西:

    首先,我想确保C++中的C结构初始化是有效的。

    struct Foo{
        int a;
        bool b;
        char* c;
        double d;
    };
    //..
    Foo arr[2]={{0, true, "a", 3.14}, {1, false, "z", 42.0}};
    

    好的,这行。但接下来,我决定检查一下换了衣服之后会发生什么 struct class

    class Bar{
     public:
        int a;
        bool b;
        char* c;
        double d;
    };
    
    //..
    
    Bar arr[2]={{0, true, "a", 3.14}, {1, false, "z", 42.0}};//works
    Bar bar;                                                 //works
    Bar bar2=arr[1];                                         //works
    //Bar bar3(2, false, "so", 7.0);                         //of course doesn't work
    //first, second, third ways works... 
    

    只要 class Bar 没有任何私有/受保护的字段(但它可以包含方法)。所以,只要编译器可以创建只使用结构的简单特性的类,就可以编译它。

    • 第一个问题:我说得对吗?

    • 第二个问题:这是编译器(在本例中是gcc)的特性,还是标准所说的?

    [编辑]

    代码 //Bar bar3(2, false, "so", 7.0); //of course doesn't work 这不是问题;)


    7 回复  |  直到 15 年前
        1
  •  2
  •   Tamas Demjen    15 年前

    尽管您称之为C样式初始化,但它的正式名称是initializer list。只能使用初始值设定项列表初始化聚合(请参阅标准中的8.5)。

    聚合是具有

    • 没有用户声明的构造函数,
    • 没有基类,
    • 没有虚拟功能。

    struct Aggregate
    {
       std::string s;
    };
    
    Aggregate ag = { "hello" };
    
        2
  •  9
  •   fredoverflow    15 年前

    我决定检查一下将struct改为类之后会发生什么。

    struct class 是成员的默认可见性和默认继承模式。 struct D : B { ... class D : public B { public: ... .

        3
  •  3
  •   dotminic    15 年前

    很正常,“/Bar bar3(2,false,“so”,7.0);”不起作用,因为您没有用该签名定义构造函数。为了使其工作,您需要在类中定义一个具有该签名的构造函数。编译器只为您生成默认构造函数和默认复制构造函数,除非您自己声明它们。

        4
  •  2
  •   slashmais    15 年前

    //Bar bar3(2, false, "so", 7.0); 您正在调用一个不存在的ctor。

        5
  •  0
  •   Etienne de Martel    15 年前

    Bar满足POD类型的要求,这意味着它可以像C结构一样初始化。作为一个类或结构对这个没有影响。

        6
  •  0
  •   Marm0t    15 年前

    两个默认构造函数:构造函数 施工员。

    1.是的-你说的对。

    它是编译器的(本例中是gcc) 特征

    你在说什么“特色”?只需重载构造函数以获得方法

        7
  •  0
  •   ArBR    15 年前

    众所周知,C++中的任何类都存在默认构造函数和默认复制构造函数,不管它们是否显式声明或不声明。我认为当您使用以下语法时会发生什么情况:

    Bar arr[2]={{0, true, "a", 3.14}, {1, false, "z", 42.0}}; 
    

    编译器推断出对象的类型,然后调用每个对象的默认构造函数,然后根据其在类定义中的位置分配每个字段。编译器无法调用默认的复制构造函数,因为在创建新对象时没有直接传递相同类型的对象,也就是说,应在以下情况下调用复制构造函数:

    Bar a;     //default constructor is called
    Bar b(a);  //default copy constructor is called
    Bar c = a; //default copy constructor is called
    

    酒吧 类,然后调试以了解实际情况。。。