【问题标题】:C++ Initialize object member of a struct that is allocated using the "new" keywordC ++初始化使用“new”关键字分配的结构的对象成员
【发布时间】:2015-04-15 03:42:15
【问题描述】:

这可能是一个复杂的问题,但我认为它有一个简单的答案。

所以我有一个包含自定义对象类型的结构:

// 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)
    };
}

上面的代码 sn-p 有语法错误,但它演示了我想要做什么。注意 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 是一个集合吗?如果没有,则需要提供构造函数。
  • ; 在结构的末尾,拜托!
  • 另外,您在此处显示的是Ctagged struct initialization syntax。 C++ 不支持。
  • @Pradhan 我相信是的。它与这里显示的代码是平行的,唯一显着的区别是成员的数量。
  • 顺便说一句,您的域名已损坏

标签: c++ struct initialization


【解决方案1】:

如果MyStruct 是一个聚合,您可以使用aggregate initialization 来避免定义构造函数:

myStructPtr = new MyStruct {{arg1, arg2}, {arg1, arg2}};

如果没有,请提供一个带有适当参数的构造函数并调用

myStructPtr = new MyStruct{arg1, arg2};

【讨论】:

  • 使用聚合初始化并不能消除“缺少';'”语法错误。还在同一行看到“MyStruct:没有适当的默认构造函数可用”。
  • 不是聚合初始化,伙计们。
  • @LightnessRacesinOrbit 我不确定我错过了什么。从 N3797,8.5.4 [dcl.init.list] 开始,第一点说上面的 new 的初始化表达式是 列表初始化。同一部分的第三点说If T is an aggregate, aggregate initialization is performed。我的答案是假设MyStruct 是一个集合。
  • [C++11: 8.5.1/1]: "一个 聚合 是一个数组或一个类(第 9 条),没有用户提供的构造函数 (12.1),没有 brace-or-equal -initializers 用于非静态数据成员 (9.2)、无私有或受保护的非静态数据成员(第 11 条)、无基类(第 10 条)和无虚函数 (10.3)。"
  • 虽然很公平:if MyStruct 是一个聚合,那么它将是聚合初始化 (TIL),因此,尽管具有误导性,但您的回答并非完全错误是措辞。只是测试! ;)
【解决方案2】:

您正在尝试使用 C 的指定初始化程序,are not part of C++。如果您有 C++11 编译器,您只需执行以下操作:

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

Live demo

【讨论】:

  • 哇!我不知道你能做到这一点。哪个列表初始化子句涵盖了这一点?当MyStruct 不是聚合时?运行条件here,我无法理解为什么允许这样做。
  • 是什么让这在 C++11 中成为可能,而不是更早的版本?
  • @Pradhan 和你的回答一样,其实我更喜欢你的回答,因为你避免提及MyClass
  • @aaronncfca 它需要列表初始化,这是 C++11 的一部分
【解决方案3】:

不知何故,您需要将您的构造链接在一起。假设您实际上想要相同的参数:

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});

还有许多其他类似的解决方案。

【讨论】:

  • 我在真正的 MyStruct 中有大约 50 个成员,每个成员在构造函数中都有几个参数,所以这对我来说不可行。
  • 它不也可以做:...MyStruct *s = new MyStruct({1,2}, {3,4}); ?
  • @aaronncfca:也许你可以发布真正的代码,而不是你刚刚在此处发布的内容 - 但这听起来你可能不想以这种方式使用初始化列表进行初始化...
  • @aaron 50 个成员?!你确定你的班级不会疯狂地太大吗?
  • @LightnessRacesinOrbit 这是一个对象列表,我想将它们放入一个结构中以更好地管理。
猜你喜欢
  • 2020-12-17
  • 2012-07-18
  • 1970-01-01
  • 2015-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多