使用“new”关键字分配内存的结构体对象成员的C++初始化方法

3
这可能是一个复杂的问题,但我认为它有一个简单的答案。
所以我有一个包含自定义对象类型的结构体:
// header1.h

struct MyStruct
{
    MyClass myObject1;
    MyClass myObject2;
};

我有一个指向MyStruct的全局指针。我将使用new关键字来分配和实例化结构体。在这样做时,我想通过初始化列表按名称构建每个myObject,如下所示。

// codeFile1.cpp

MyStruct *myStructPtr;

int main()
{
    myStructPtr = new MyStruct
    {                                     //syntax error: missing ';'
        .myObject1 = MyClass(arg1, arg2),
        .myObject2 = MyClass(arg1, arg2)
    };
}

上面的代码片段有语法错误,但它演示了我想要做的事情。请注意, MyClass 没有默认构造函数,因此必须给出参数列表。
谢谢!
编辑 - 结论
如指出的那样,我的初始化列表是 C 风格的,无法工作。不幸的是,C++11 初始化列表不符合我的编译器要求,将所有参数抛到构造函数中的选项也不切实际。
因此,我采用了另一种解决方案,并将指针结构更改为以下内容:
// header1.h

struct MyStruct
{
    MyClass *myObjectPtr1;
    MyClass *myObjectPtr2;
};

// codeFile1.cpp

MyStruct myStruct;

int main()
{
    myStructPtr.myObjectPtr1 = new MyClass(arg1, arg2);
    myStructPtr.myObjectPtr2 = new MyClass(arg1, arg2);
}

感谢大家!

MyStruct是一个聚合体吗?如果不是,您需要提供一个构造函数。 - Pradhan
请在结构体末尾加上分号; - Christophe
另外,你展示的是“C”的 tagged struct initialization syntax。而C++不支持该语法。 - Pradhan
@Pradhan 我也这么认为。它与此处显示的代码并行,唯一显著的区别是成员数量。 - Aaron Campbell
顺便说一下,你的域名有问题。 - Lightness Races in Orbit
@LightnessRacesinOrbit 那是一段时间前的事了,是的。我忘记从我的个人资料中编辑它。 - Aaron Campbell
3个回答

3
如果MyStruct是一个聚合体,您可以使用聚合初始化来避免定义构造函数:
myStructPtr = new MyStruct {{arg1, arg2}, {arg1, arg2}};

如果没有提供相应参数的构造函数,请提供一个并调用它。
myStructPtr = new MyStruct{arg1, arg2};

使用聚合初始化不能解决“missing ';'”语法错误。同时在同一行上出现“MyStruct:没有适当的默认构造函数可用”的错误。 - Aaron Campbell
这不是聚合初始化,伙计们。 - Lightness Races in Orbit
@LightnessRacesinOrbit 我不确定我漏掉了什么。从N3797,8.5.4 [dcl.init.list],第一点说上面的初始化表达式对于new列表初始化。同一节的第三点说如果T是一个聚合体,则执行聚合初始化。而我的答案以MyStruct是一个聚合体为前提。 - Pradhan
- Lightness Races in Orbit
说得好,不过:如果MyStruct是一个聚合体,那么它将是聚合初始化(TIL),因此,尽管有些误导,但你的回答在措辞上并没有严格错误。只是测试而已!;) - Lightness Races in Orbit
@LightnessRacesinOrbit 我感到受冒犯了!我的答案有一个if子句和一个else子句 :) - Pradhan

2

您正在尝试使用C的指定初始化器,这不是C++的一部分。如果您有一个C++11编译器,您可以简单地执行以下操作:

MyStruct *myStructPtr = new MyStruct
{
    MyClass(arg1, arg2),
    MyClass(arg1, arg2)
};

在线演示


哇!我不知道一般情况下你可以这样做。当MyStruct不是聚合体时,哪个列表初始化子句涵盖了它?在这里运行条件,我无法理解为什么允许这样做。 - Pradhan
这在C++11中成为可能,而之前不行的原因是什么? - Aaron Campbell
@Pradhan,其实你的回答和我的一样,不过我更喜欢你的回答,因为你避免了提到 MyClass - Praetorian
2
@aaronncfca 这需要使用C++11的列表初始化。 - Praetorian

1

你需要以某种方式将你的结构链在一起。假设你实际上想要相同的参数:

struct MyStruct
{
    MyStruct(int arg1, int arg2) : myObject(arg1, arg2), myObejct2(arg1, arg2) {}
    MyClass myObject1;
    MyClass myObject2;
};

MyStruct *s = new MyStruct(34, 42);

或者类似这样的内容:
struct MyStruct
{
    MyStruct(const MyClass& a1, const MyClass& a2) : myObject(a1), myObejct2(a2) {}
 .... 
};

MyStruct *s = new MyStruct(MyClass(1,2), MyClass(3,4));

或者在C++11的初始化列表中:
MyStruct *s = new MyStruct({1,2}, {3,4});

许多类似的解决方案都可以找到。

@aaronncfca:也许你可以发布真正的代码,而不是为了在这里发布而编造的东西——但那听起来你可能并不想以那种方式使用初始化列表进行初始化... - Mats Petersson
@aaron 50个成员?!你确定你的班级不是过于庞大了吗? - Lightness Races in Orbit
@LightnessRacesinOrbit 这是一个对象列表,我想将其放入结构体中以便更好地管理。 - Aaron Campbell
@aaronncfca:你可以用无数种方法来实现它。对于那个问题的答案可以写一本书。说到书,你用的是哪一本? - Lightness Races in Orbit
给出真实的代码,我们可能能够提供更有用的建议。但是通常情况下,在一个结构体中拥有50个对象似乎是错误的。 - Mats Petersson
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接