c++ 中的基本运算符重载语法
我很难形成一个我想问的问题,所以让我举个例子:
假设我们正在开发一个 3d 系统,在该系统中我们定义了一个向量类 Vec3。出于明显的原因,我们重载了一些算术运算符。其中我们重载 * 运算符,以便它将返回两个向量的点积。现在我们的代码应该如下所示:
class Vec3{
private:
float x, y, z;
public:
float operator*(const Vec3&) const; //dot product
.
.
.
现在假设我们希望能够通过使用 * 运算符来缩放向量,例如浮点数。这可以通过声明以下内容来完成:
Vec3 operator*(const float) const;
friend Vec3 operator*(const float, const Vec3&);
这会产生两个重载,并且我想知道是否有一种方法可以只用一个重载,即我们声明它而不是上面的两行:
friend Vec3 operator*(const Vec3&, const Vec3&);
然后为 Vec3 向量添加默认值以处理浮点转换。
最后一个示例适用于:
Vec3 someVec3 = 1.0 * otherVec3; //through friend Vec3 operator*(const float, const Vec3&)
但不适用于此:
Vec3 someVec3 = otherVec3 * 1.0;
因为编译器不知道使用两者中的哪一个:
friend Vec3 operator*(const float, const Vec3&); //the one we want to use
or
float operator*(const Vec3&) const; //the one for the dot product
有什么建议吗?
谢谢你!
I’m having a hard time forming a question of what I’m trying to ask so let me give you an example:
Say we are working on a 3d system where we have defined a vector class, Vec3. We overload some arithmetic operators for obvious resons. Among these we overload the *operator so that it will return the dot product of two vectors. Now our code should look something like this:
class Vec3{
private:
float x, y, z;
public:
float operator*(const Vec3&) const; //dot product
.
.
.
Now say that we want to be able to scale our vector by using the *operator with something, say a float. This could be done by declaring the following:
Vec3 operator*(const float) const;
friend Vec3 operator*(const float, const Vec3&);
This yeilds two overloads and I’m wondering if there’s a way to do it with just one, i.e. say we declare this instead of the above two lines:
friend Vec3 operator*(const Vec3&, const Vec3&);
and then add default values for the Vec3 ctor to handle the convertion from float.
This last example would work for:
Vec3 someVec3 = 1.0 * otherVec3; //through friend Vec3 operator*(const float, const Vec3&)
however not for this:
Vec3 someVec3 = otherVec3 * 1.0;
as the compiler wouldn’t know which of the two to use:
friend Vec3 operator*(const float, const Vec3&); //the one we want to use
or
float operator*(const Vec3&) const; //the one for the dot product
Any suggestions?
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在这种情况下,我最初建议不要重载运算符,因为您的用户如何知道
*
是否表示点积或叉积(两者都是合理的含义,具体取决于预期的客户端使用)。我实际上建议不支持operator*
并使用dot
、cross
和scale
成员。这样您就不必担心多次过载,并且您的用户很清楚他们将获得什么。但是,如果您确实想继续使用运算符,那么有两个重载也没有什么问题。创建一个虚拟
Vec3
来进行缩放不仅在语义上不正确,而且还会增加少量不必要的开销。In this case I would initially advise against operator overloading, because how are your users to know if
*
represents dot or cross product (both are reasonable meanings depending on expected client use). I would actually suggest just not supportingoperator*
and do it withdot
,cross
andscale
members. Then you don't have to worry about multiple overloads and it's clear to your users what they're getting.However if you do want to go ahead with the operators, there's nothing wrong with having two overloads. Creating a dummy
Vec3
to do scaling is not only semantically incorrect it's going to add a small amount of unneeded overhead.Boost.Operators 可以完成大部分样板文件为你工作。例如:
Boost.Operators can do most of the boiler-plate work for you. E.g.:
几个重载并没有什么问题,尤其是如果它们可以很容易地相互实现的话:
很难得到比这更简单的了!
There is nothing wrong in a couple of overloads, especially not if they can easily be implemented in terms of each other:
It is hard to get it simpler than that!