使用const字段初始化struct数组,这些const字段没有默认构造函数

时间:2017-11-10 07:15:43

标签: c++ arrays struct const

我想定义一个结构数组,但这不起作用,因为它有一个没有默认构造函数的const字段。

Struct是SDK的一部分,如下所示:

struct SParametricParamDef
{
    const TXString          fUniversalName;
    SResString              fLocalizedName;
    const TXString          fDefaultImperial;
    const TXString          fDefaultMetric;
    EFieldStyle             fFieldStyle;
    short                   fChoicesChcID;
};

TXString没有默认构造函数。所以关注失败:

SParametricParamDef *arrParams = new SParametricParamDef[size]; // <= throws compile time exception
for (int i = 0; i < size; i++)
{
    arrParams[i] = params[i].def; // <= also throws an exception, because operator = is not available
}

有什么方法可以解决这个问题吗?结果我需要一个SParametricParamDef*,因为这个数组再次在SDK中使用......

信息

在旧的SDK版本中,const TXSTringconst char*然后我没有遇到问题......现在我需要调整我的代码以使用新结构......

3 个答案:

答案 0 :(得分:1)

您获得的错误主要不是关于operator =,而是关于您使用const成员默认构造对象的事实。这将使它们成为不可变的,并且当您在循环中尝试时,任何修改它们的尝试都必须失败。 幸运的是,你可以使用emplace_back在向量内初始化SParametricParamDef对象,而不需要默认构造和赋值的间接:

std::vector<SParametricParamDef> arrParams;
for(std::size_t n = 0; n < size; ++n) {
    arrParams.emplace_back(params[n].def);
}

这应该最小化复制量,而无需修改struct定义。

答案 1 :(得分:0)

编译器告诉您要求创建TXString而不指示如何初始化它。很难知道如何解决创建TXString对象的问题,因为你没有给出类的构造函数列表,但是因为它代表你需要对代码进行更改。给了。解决这个问题的一些方法如下:

最明显的是为SParametricParamDef添加一个默认构造函数,用于初始化TXString个对象:

struct SParametricParamDef
{
    SParametricParamDef() : fUniversalName(...), ... {}
...

另一种方法,假设变量为const 可能使它们成为const static

为简单起见,请说TXString对象如下:

struct TXString{
    TXString(char a) : _a(a) {}
    char _a;
};

然后,您可以将SParametricParamDef的声明更改为:

struct SParametricParamDef
{
    const static TXString fUniversalName;
...

然后在您的实现文件中定义fUniversalName,如下所示:

const TXString SParametricParamDef::fUniversalName('D');

另一种方法可能是将TXString对象包装在另一个 具有默认构造函数的对象中:

struct TXStringWrapper {
    TXStringWrapper() : _s(...) {} // [1]
    const TXString& get() { return _s; }

private:
    TXString _s;
}

在[1]处,您可以以任何特定的非默认方式创建TXString

答案 2 :(得分:0)

这看起来像是使用展示位置新的示例:

html,
body {
   overflow:hidden
}

如果在释放数组之前它不是微不足道的话,你应该明确地调用析构函数:

SParametricParamDef *arrParams = (SParametricParamDef *) new char[size * sizeof(*arrParams)];

for (int i = 0; i < size; i++)
{
    // constructs an object in a pre-allocated memory
    new(arrParams+1) SParametricParamDef(params[i].def);
}

这是相当古老的,因为它模仿C中结构的初始化,但它是我知道构建只有非平凡构造函数的对象数组的唯一方法(AFAIK,for (int i = 0; i < size; i++) { ~SParametricParamDef(arrParams+1); } delete[] ((char *) arrParams); 方式需要可复制或可移动的物体)