使数学向量类能够感知初始化列表
我有一个数学向量类,其设计如下:
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);
我听说可以通过实现初始化列表构造函数来使用 C++0x 缩短它,所以它可以写出类似这样的内容:
Vector3D vec1 = { 1.0, 1.0, 1.0 };
实现这个的正确方法是什么?
更新
花括号语法对于此类来说确实是开箱即用的!感谢您的回答和评论!
另外,我做了一些综合性能测试,试图测量构造函数初始值设定项列表是否比构造函数中的成员变量分配提供加速。下面是我使用 g++ 4.6.1 得到的结果:
原样(构造函数和自定义复制构造函数中的成员赋值):
中位数:634860 ns 中位数,CPI:15.8715 ns 平均:636614 纳秒 平均,CPI:15.9154 ns
使用构造函数初始值设定项列表和自定义复制构造函数。自定义复制构造函数:
中位数:634928 ns 中位数,CPI:15.8732 ns 平均:636312 纳秒 平均,CPI:15.9078 ns
使用构造函数初始值设定项列表 &默认复制构造函数:
中位数:860337 ns 中位数,CPI:21.5084 ns 平均:864391 纳秒 平均,CPI:21.6098 ns
一些结论:
- 在上面介绍的数学向量类的情况下,构造函数初始值设定项列表不会比成员变量赋值提供加速。
- 自定义复制构造函数比默认复制构造函数快 35% 以上。
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:
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:
- 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
大括号初始化适用于各种构造函数,在这种情况下您不需要初始化列表构造函数参数。相反,初始值设定项列表适用于变量内容,例如动态容器的内容,但不适用于固定长度的构造函数参数。所以你可以说:
一切都会好起来的。
但请注意,您应该真正初始化类成员而不是分配它们:
您也不应该编写复制构造函数,因为它并不比默认提供的更好。赋值运算符也是如此。
(就我个人而言,我对
float[]
构造函数感到不舒服;最好使用std::array
;但是同样,您可能从一开始就使用这样的数组作为您的 3D 向量类型,而根本不用编写自定义类。)最后,您可以在最后一个示例中组合构造初始化列表和初始化列表构造函数制作向量列表:
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:
and all will be fine.
Note however that you should really initialize your class members rather than assigning them:
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 astd::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: