C ++:如何使用初始化列表初始化内部结构的成员?

时间:2011-07-21 20:28:58

标签: c++ struct initialization

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

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

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

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

 
    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.

3 个答案:

答案 0 :(得分:4)

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

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

在我们等待更多编译器完全支持此功能的过程中,在嵌套struct中添加构造函数是一个非常可行的选项。

答案 1 :(得分:0)

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

  

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

在决定是否使用结构或类时,要问的问题是:此对象是否存在不变?不变量是对对象的有效状态的描述。如果您可以定义一个不变量,那么您还可以定义无效状态,并且您应该仅通过成员函数提供对内部成员变量的访问,以确保可以维护有效状态。这最好由一个班级来完成。但是,如果任何旧的国家会这样做;然后使用结构。

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

答案 2 :(得分:0)

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

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之类的东西可能更喜欢使用名为x和{{的属性1}}超过yfirst。)