C++ 使数学向量类具有初始值设定项列表意识

C++ 使数学向量类具有初始值设定项列表意识,c++,c++11,initializer-list,C++,C++11,Initializer List,我有一个数学向量类,设计如下: class Vector3D { public: float x; float y; float z; public: Vector3D() {} Vector3D(float xx, float yy, float zz = 0.0) { x=xx; y=yy; z=zz; } Vector3D(const float v[]) { x=v[0]; y=v[1]; z=v[2]; } Vector3D(c

我有一个数学向量类,设计如下:

class Vector3D {
public:
    float x;
    float y;
    float z;

public:
    Vector3D() {}
    Vector3D(float xx, float yy, float zz = 0.0) { x=xx; y=yy; z=zz; }
    Vector3D(const float v[]) { x=v[0]; y=v[1]; z=v[2]; }
    Vector3D(const Vector3D& v) { x=v.x; y=v.y; z=v.z; }

    // math member methods
    // ...
};
我曾经使用以下方法在堆栈上创建Vector3D类型变量:

Vector3D vec1 = Vector3D(1.0, 1.0, 1.0);
我听说a可以通过实现一个初始值设定项列表构造函数来缩短C++0x的使用时间,因此可以编写如下内容:

Vector3D vec1 = { 1.0, 1.0, 1.0 };
实现这一点的正确方法是什么

更新 花括号语法对于这个类来说真的是开箱即用!谢谢你的回答和评论

此外,我还做了一些综合性能测试,试图测量构造函数初始值设定项列表是否比构造函数中的成员变量赋值更快。下面是我使用g++4.6.1获得的结果:

  • 原样(构造函数和自定义副本构造函数中的成员分配):

  • 使用构造函数初始值设定项列表和自定义副本构造函数:

    Median:       634860 ns
    Median, CPI:  15.8715 ns
    Average:      636614 ns
    Average, CPI: 15.9154 ns 
    
    Median:       634928 ns
    Median, CPI:  15.8732 ns
    Average:      636312 ns
    Average, CPI: 15.9078 ns
    
    Median:       860337 ns
    Median, CPI:  21.5084 ns
    Average:      864391 ns
    Average, CPI: 21.6098 ns
    
  • 使用构造函数初始值设定项列表和默认副本构造函数:

    Median:       634860 ns
    Median, CPI:  15.8715 ns
    Average:      636614 ns
    Average, CPI: 15.9154 ns 
    
    Median:       634928 ns
    Median, CPI:  15.8732 ns
    Average:      636312 ns
    Average, CPI: 15.9078 ns
    
    Median:       860337 ns
    Median, CPI:  21.5084 ns
    Average:      864391 ns
    Average, CPI: 21.6098 ns
    
  • 一些结论:

    • 对于上面介绍的math vector类,构造函数初始值设定项列表不提供成员变量赋值的加速比
    • 自定义复制构造函数比默认复制构造函数快35%以上

    大括号初始化适用于所有类型的构造函数,在本例中不需要初始化器列表构造函数参数。相反,初始值设定项列表用于变量内容,就像动态容器的内容一样,但不用于固定长度的构造函数参数。所以你可以说:

    vector3D v { 1, 1, 1 };
    
    一切都会好起来的

    但是请注意,您应该真正初始化类成员,而不是分配它们:

    Vector3D(float xx, float yy, float zz = 0.0) : x(xx), y(yy), z(zz) { }
    Vector3D(const float v[]) : x(v[0]), y(v[1]), z(v[2]) { }
    
    您也不应该编写一个复制构造函数,因为它并不比默认情况下提供的构造函数更好。赋值运算符也是如此

    (就我个人而言,我对
    float[]
    构造函数感到不舒服;最好使用
    std::array
    ;但是,您可以从一开始就使用这样的数组作为3D向量类型,而不必编写自定义类。)

    最后,在生成向量列表的最后一个示例中,您可以组合构造初始值设定项列表和初始值设定项列表构造函数:

    std::list<Vector3D> l { { 1.0, 2.0, 3.0}, { 1.5, 3.0, 4.4 }, { 0.0, -1.2, 4.1 } };
    
    std::list l{{1.0,2.0,3.0},{1.5,3.0,4.4},{0.0,-1.2,4.1};
    
    您已经可以编写:
    Vector3D-vec1(1.0、1.0、1.0)是否仍要使用初始值设定项列表?实际上,初始值设定项列表赋值运算符可能比初始值设定项列表构造函数有用得多代码。初始值设定项列表有什么好处@本:
    vec1={2.0,2.0,2.0}也可以按原样用于赋值。当您甚至还没有得到构造函数初始值设定项列表时,考虑初始值设定项列表构造函数有点快。至少说
    Vector3D(float-xx,float-yy,float-zz=0.0):x(xx),y(yy),z(zz){}