Reputation: 8126
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?
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:
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
Using constructor initializer list & custom copy constructor:
Median: 634928 ns
Median, CPI: 15.8732 ns
Average: 636312 ns
Average, CPI: 15.9078 ns
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:
Upvotes: 2
Views: 839
Reputation: 477368
Brace-initialization works for all sorts of constructors, and you don't need an initializer-list constructor argument in this case. On the contrary, initializer lists are for variable content, like the content of a dynamic container, but not for fixed-length constructor arguments. So you can just say:
vector3D v { 1, 1, 1 };
and all will be fine.
Note however that you should really initialize your class members rather than assigning them:
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]) { }
You also shouldn't write a copy constructor, since it does no better then the one that's provided by default. The same goes for the assignment operator.
(Personally, I don't feel comfortable with the float[]
constructor; it'd be better to use a std::array<float, 3>
; but then again you might just use such an array as your 3D-vector type from the start and not bother writing a custom class at all.)
Finally, you can combine construct-initializer-lists and initializer-list-constructors in this last example of making a list of vectors:
std::list<Vector3D> l { { 1.0, 2.0, 3.0}, { 1.5, 3.0, 4.4 }, { 0.0, -1.2, 4.1 } };
Upvotes: 6