重载运算符作为复制构造函数的参数

时间:2018-04-01 23:07:07

标签: c++

我想使用复制构造函数来重载operator*的结果。我找到了这样做的方法:通过返回运算符的引用。我想知道的是:

  1. 这没关系吗?
  2. 以下是示例:

    class Foo{
        public:
            double x,y,z;
            Foo() : x(0), y(0), z(0) {};
            Foo(double xi, double yi, double zi) : x(xi), y(yi), z(zi) {};
            Foo(const Foo &bar) : x(bar.x), y(bar.y), z(bar.z) {};
    };
    
    Foo& operator * (const double &b, Foo &a){ // Yep, I want to modify a
        a.x *= b;
        a.y *= b;
        a.z *= b;
        return a;
    }
    
    int main(){
        Foo temp;
        Foo bar = 4*temp; // Here is what I want to do!
    
        return 0;
    }
    

3 个答案:

答案 0 :(得分:1)

我认为

const Foo operator *(const double& b, Foo& a)
{
    a.x *= b;
    a.y *= b;
    a.z *= b;

     return a;
}
如果您真的想要修改a

可能就是您想要的。我个人会放弃参考。返回类型上的const是必要的,以确保类似:

Foo a, c;
double b = 1.0;

(a * b) = c;

不合法。

您的方法不是标准做事的方式。通常,您将拥有:

const Foo operator *(const double& b, const Foo& a)
{
    return Foo(a.x *b, a.y * b, a.z * b);
}

这是一个标准的,可交换乘法,其中操作数保持不变。

答案 1 :(得分:1)

  

1这没关系吗?

它形成良好,行为定义明确。然而,这是非常规的,因为二进制算术运算符通常不会修改其操作数。这对代码的用户来说会非常混乱。

与定义二进制算术运算符的常用方法相比,您的方法也更具限制性:

Foo get_foo();         // for exposition
Foo bar = 4*get_foo(); // oops, this doesn't work

鉴于非传统性,证明的限制以及与传统方法相比缺乏效益,我会说它不合适

  

2标准运营商是否采用类似的方法?例如:

int b = 4*4;

没有。内置二进制算术运算符都不是这样的。标准库中的任何重载都没有这样做(我没有检查,但我仍然有信心)。

我建议采用通常的方法,特别是考虑到这是用于3d矢量:

A operator*(const B& lhs, const A& rhs);

操作数是const引用,因此它们不会被修改,结果是一个可用于初始化变量的新实例。

PS。您的自定义复制构造函数除了隐式复制构造函数之外什么也没做,因此它似乎是多余的。

答案 2 :(得分:1)

使用operator *,我们希望:

  • 两个输入保持未修改
  • 要返回的对象(按值)。

给了我们以下签名:

Foo operator * (double a, Foo const & b);

如果您想修改temp = 4*temp,请改为使用operator *=作为temp *= 4;,修改temp并返回其引用:

Foo & operator *= (Foo & a, double b) {
    a.x *= b;
    a.y *= b;
    a.z *= b;
    return a;
}

<强> Demo