2

I have a math vector class that is designed as follows:

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

I used to use the following to create a Vector3D-type variable on the stack:

Vector3D vec1 = Vector3D(1.0, 1.0, 1.0);

I heard a can shorten this up with C++0x by implementing an initializer list constructor, so it will be possible to write something like:

Vector3D vec1 = { 1.0, 1.0, 1.0 };

What is the right way to implement this?

Update

The curly braces syntax really works out of the box for this class! Thanks for the answer and the comments!

Also, I did some synthetic performance tests trying to measure if constructor initializer list gives a speedup over member variable assignment in a constructor. Below is the results I've got with g++ 4.6.1:

  1. As is (member assignment in a constructor & custom copy constructor):

    Median:       634860 ns
    Median, CPI:  15.8715 ns
    Average:      636614 ns
    Average, CPI: 15.9154 ns 
    
  2. Using constructor initializer list & custom copy constructor:

    Median:       634928 ns
    Median, CPI:  15.8732 ns
    Average:      636312 ns
    Average, CPI: 15.9078 ns
    
  3. Using constructor initializer list & default copy constructor:

    Median:       860337 ns
    Median, CPI:  21.5084 ns
    Average:      864391 ns
    Average, CPI: 21.6098 ns
    

Some of the conclusions:

  • The constructor initializer list does not give a speedup over member variable assignment in the case of the math vector class presented above.
  • The custom copy constructor is more than 35% faster than the default copy constructor.
4

1 回答 1

6

大括号初始化适用于各种构造函数,在这种情况下您不需要初始化列表构造函数参数。相反,初始化列表用于可变内容,例如动态容器的内容,但不适用于固定长度的构造函数参数。所以你可以说:

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[];最好使用 a std::array<float, 3>; 但是你可能从一开始就使用这样的数组作为你的 3D 向量类型,根本不用费心编写自定义类.)

最后,您可以在创建向量列表的最后一个示例中组合construct-initializer-lists 和initializer-list-constructors:

std::list<Vector3D> l { { 1.0, 2.0, 3.0}, { 1.5, 3.0, 4.4 }, { 0.0, -1.2, 4.1 } };
于 2012-02-03T22:02:14.993 回答