在POD中强制默认初始化构造函数

Force Default Initialized Constructor in POD?

本文关键字:默认 初始化 构造函数 POD      更新时间:2023-10-16

是否有办法强制将默认初始化的构造函数用于POD类型?所以所有的值,比如整数,都初始化为0 ?

struct MyPod
{
    int a; // whether a is initialized to zero is dependent on creation method
};
struct MyOtherNonPod
{
    int b;
    MyOtherNonPod() : b(0) // b initialized to zero regardless of creation method
    {}
};
MyPod* pod = new MyPod; // pod->a not initialized
MyOhterNonPod* otherPod = new MyOtherNonPod; // otherPod->b is initialized to zero

有没有一种方法可以做到这一点,而不必定义一个构造函数和手动初始化所有的变量?而是强制总是调用默认初始化的构造函数?

MyPod* pod = new MyPod{}; // pod->a is default initialized to zero

是否有一种方法可以强制使用上述构造函数,而不管{}是否存在?我有很多变量在我的POD类与冗长的名称,我宁愿消除不确定性,类不会被初始化为零取决于我是否默认初始化。无需手动设置。

POD的定义是不能有用户定义的构造函数,并且所有成员必须是POD。

所以,不,你不能。但是看起来你不需要POD。

#include <iostream>
struct NonPOD {
    int    i = {};
    double d = {};
    // NonPOD() = default;
};
int main() {
    NonPOD x;
    std::cout << x.i << ", " << x.d << "n";
}

无法执行您的请求,因为POD可能没有用户声明的构造函数。一种替代方法是创建一个以POD作为基类的类:

struct MyPodV : MyPod
{
    MyPodV: MyPod() {}
};

然后您可以创建MyPodV对象,并且仍然将它们与期望MyPod的函数一起使用。

当然有一个问题,你可能会忘记做一个MyPod而不是MyPodV,所以这并没有真正获得多少要求人们做MyPod x{}。也许您可以使用一种命名约定来避免意外创建POD。

恐怕c++中没有默认的自动初始化功能,至少不是您所期望的那样。

据我所知,至少从c++11标准开始,你有三种选择:

  1. 为每个结构添加默认构造函数,这可能有点繁琐。

    //Init by default constructor
    struct POD3{
        int a;
        int b;
        char c;
        POD3(): a{}, b{}, c{} {};
    };
    POD3 stackPod3;
    POD3* heapPod3 = new POD3;        
    
  2. 为你的结构体的每个成员添加一个默认初始化,这就是我要做的。

    //Init by field
    struct POD{
        int a{};
        int b{};
        char c{};        
    };
    POD stackPod;
    POD* heapPod = new POD;
    
  3. 或者冒险在创建对象时依赖于正确的语法,这是最糟糕的选择。

    //Init by object creation
    struct POD2{
        int a;
        int b;
        char c;        
    };
    POD2 stackPod2{};
    POD2* heapPod2 = new POD2{};
    

正如上面已经提到的,我个人的观点是,第二种选择对于代码的可读性来说是最好的,并且丢失成员的可能性非常低。

是的,在c++ 11中有一种方法可以做到。下面是代码:

#include <iostream>
struct MyPod
{
    int a; // whether a is initialized to zero is dependent on creation method
};

int main()
{
    MyPod* pod = new MyPod{ 23 }; // pod->a initalized to 23
}

在这种情况下有必要使用花括号,因为这是在依次初始化每个成员。如果你在MyPod中有更多的类型,那么它可能看起来像这样:

#include <iostream>
struct MyPod
{
    int a; 
    bool b;
    double c;
};

int main()
{
    MyPod* pod = new MyPod{ 23, false, 32.93 }; 
}