Как решить проблему с перегрузкой оператора?

Рейтинг: 0Ответов: 1Опубликовано: 11.03.2023

У меня имеется такая перегрузка оператора для класса точка:

Point operator * (double c) {
        Point temp;
        temp.x = this -> x * c;
        temp.y = this -> y * c;
        temp.z = this -> z * c;
        return temp;
    }

При такой перегрузке работает только такая запись:

Point p1(1,2,3);
double c = 2;
Point p2 = p1 * 2;

Однако не работает такая запись:

Point p1(1,2,3);
double c = 2;
Point p2 = 2 * p1;

Как я понял, то это не работает, так как мы не вызываем перегруженный оператор для класса Point. Можно ли сделать так, чтобы перегрузка оператора работала в обе стороны (Point на число и число на Point)

Ответы

▲ 2

Например, так, сделав оператор свободным:

struct Point
{
    double x,y,z;
    Point(double x = 0, double y = 0, double z = 0)
        :x(x),y(y),z(z){}
};

Point operator * (const Point& t, double c)
{
    return Point(t.x*c,t.y*c,t.z*c);
}

Point operator * (double c, const Point& t)
{
    return Point(t.x*c,t.y*c,t.z*c);
}

Или даже, чтоб избежать дублирования кода,

Point operator * (double c, const Point& t)
{
    return t*с;
}

Update к

я хотел это сделать в рамках одной перегрузки

Можно и так, например, простейший вариант

struct Point
{
    double x,y,z;
    Point(double x = 0, double y = 0, double z = 0)
        :x(x),y(y),z(z){}
};

struct proxy
{
    Point p;
    double d;
    bool is_double;
    proxy(double x):d(x),is_double(true){}
    proxy(const Point& p):p(p),is_double(false){}
};

Point operator * (const proxy& t, const proxy& d)
{
    if (d.is_double && !t.is_double) return Point(t.p.x*d.d,t.p.y*d.d,t.p.z*d.d);
    if (!d.is_double && t.is_double) return Point(d.p.x*t.d,d.p.y*t.d,d.p.z*t.d);
    return Point();
}

Но тут есть свои подводные камни, типа умножения Point на Point...