【问题标题】:C++: How do you initialize an internal struct's members using an initialization list?C++:如何使用初始化列表初始化内部结构的成员?
【发布时间】:2011-07-21 20:28:57
【问题描述】:

这确实是两个问题,如下所示:

目前我有一些公共的内部辅助结构(严格用于将数据作为一个对象传递),在构造类的实例期间,我尝试使用初始化列表而不是赋值,但编译器抱怨个别结构成员所以我在结构中添加了构造函数……但这似乎是我走错了路。

有没有办法在不使用构造函数的情况下在初始化列表中初始化结构?

这些助手会更适合作为外部类吗?

 
    class Foo {

    public:
    //...
        struct Bar {
            double mass;
            std::pair<double, double> gravMod;
            std::pair<double, double> position;
            std::pair<double, double> velocity;
            bool falling;
            Bar() : mass(0.0), gravMod(std::make_pair(0.0, 0.0)), position(std::make_pair(0.0, 0.0)), velocity(std::make_pair(0.0, 0.0)), falling(false) { };
            Bar(double _mass, std::pair<double, double> _gravMod, std::pair<double, double> _position, std::pair<double, double> _velocity, bool _falling) 
             : mass(_mass), gravMod(_gravMod), position(_position), velocity(_velocity), falling(_falling) { }
            Bar(const Bar& other) 
                : mass(other.mass), gravMod(other.gravMod), position(other.position), velocity(other.velocity), falling(other.falling) { }
        };

        struct Baz {
            std::pair<double, double> acceleration;
            std::pair<double, double> force;
            Baz() : acceleration(std::make_pair(0.0, 0.0)), force(std::make_pair(0.0, 0.0)) { }
            Baz(std::pair<double, double> _acceleration, std::pair<double, double> _force) 
                : acceleration(_acceleration), force(_force) { }
            Baz(const Baz& other) : acceleration(other.acceleration), force(other.force) { }
        };

    //...
    protected:
    //...
    private:
        Bar _currBar;
        Bar _prevBar;
        Baz _currBaz;
        Baz _prevBaz;
    };

 

编辑

示例及其相关错误:

 
Foo::Foo() : _currBar{0.0, std::make_pair(0.0, 0.0), std::make_pair(0.0, 0.0), std::make_pair(0.0, 0.0), false}, _currBaz{std::make_pair(0.0, 0.0), std::make_pair(0.0, 0.0)} { }
 

_currBar{ 抛出:expected '('。第一个} 抛出:expected';'

 
Foo::Foo() : _currBar.mass(0.0), _currBar.gravMod(std::make_pair(0.0, 0.0)), _currBar.position(std::make_pair(0.0, 0.0)), _currBar.velocity(std::make_pair(0.0, 0.0)), _currBar.falling(false) { }
 

第一个_currBar. 抛出:expected '('。所有_currBar. 之后抛出Member 'Foo::_currBar' has already been initialized.

【问题讨论】:

  • “我在结构中添加了构造函数……但这似乎我走错了路。”如果你问我,这听起来不错……
  • 为什么您认为添加构造函数会走错路?
  • 如果不在构造函数中,你将如何在这些结构的每个实例中初始化成员?
  • 编译器投诉的具体内容是什么?你不喜欢你的代码什么?

标签: c++ struct initialization


【解决方案1】:

在 C++03 中,无法初始化嵌套 struct 的各个字段,也无法初始化嵌套数组的各个字段。在 C++0x(我猜现在是 C++11)中,他们放宽了这个限制,您可以使用如下语法初始化嵌套的 structs:

Foo::Foo() : _currBar{fieldOneValue, fieldTwoValue, /* ... */, fieldNValue}, /* ... etc ... */

在您的嵌套 structs 中添加构造函数是一个非常可行的选择,因为我们正在等待更多编译器完全支持此功能。

【讨论】:

  • 建议的数组初始化语法不适用于 VS2010 MSVC10。请参阅编辑以获取解释。
  • @Casey-我从来没有建议它确实有效。上面的代码在提议的 C++0x 标准中,这意味着几年后编译器将支持它。在那之前,您必须将构造函数放入您的辅助结构中才能使其正常工作。
【解决方案2】:

只要保持以下内容,您使用的方法就没有问题:

严格用于将数据作为一个对象传递

在决定是使用结构还是类时,要问的问题是:该对象是否存在不变量?不变量是对构成对象有效状态的描述。如果您可以定义不变量,那么您也可以定义 invalid 状态,并且您应该仅通过成员函数提供对内部成员变量的访问,以确保可以保持有效状态。这最好由班级执行。但是,如果任何旧状态都可以;然后使用结构。

您的构造函数只是提供合理的默认值,而不是试图保持有效状态,因此在结构中使用它们没有任何问题。

【讨论】:

    【解决方案3】:

    原则上你可以不使用构造函数:

    Foo::Foo(): _currBar(), _prevBar(), _currBaz(), _prevBaz() {}
    

    此语法零初始化无构造函数的对象(将所有字段设置为 0 / 调用它们的默认构造函数)。

    如果你想要一个带参数的构造函数,你可以使用辅助函数:

    Bar make_bar(double mass, std::pair<double, double> gravMod, std::pair<double, double> position, std::pair<double, double> velocity, bool falling)
    {
        Bar bar = { mass, gravMod, position, velocity, falling };
        return bar;
    }
    
    Foo::Foo(args...): _currBar(make_bar(args...)), ...
    

    在任何情况下,您都不需要添加复制构造函数。编译器会生成一个复制构造函数来做这件事。

    (顺便说一句,当数学向量类更合适时,我可能不会使用 std::pair。我认为,position 之类的东西可以使用名为 xy 的属性而不是 firstsecond.)

    【讨论】:

      猜你喜欢
      • 2011-05-11
      • 1970-01-01
      • 2022-01-11
      • 2016-06-23
      • 2011-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多