Переопределение = оператор в C ++ - PullRequest
1 голос
/ 20 октября 2010

Я пытаюсь переопределить оператор =, чтобы я мог изменить свой класс Point на класс Vector3.

Point tp = p2 - p1;
Vec3 v;
v = tp;

Проблема, с которой я сталкиваюсь, заключается в том, что у "v" все члены x, y, z будут все время равны нулю.

Vec3.h:

Vec3 operator =(Point a) const;

Vec3.cpp:

Vec3 Vec3::operator =(Point a) const
    {
        return Vec3(a.x,a.y,a.z);
    }

Еще раз спасибо за помощь:)

Ответы [ 8 ]

7 голосов
/ 20 октября 2010

Это было давно, но я думаю, что вы хотите

Vec3& Vec3::operator=(const Point &a) 
{
    x = a.x; y = a.y; z = a.z;

    return *this;  // Return a reference to myself.
}

Назначение изменяет 'this', поэтому оно не может быть постоянным.Он не возвращает новый Vec3, он модифицирует существующий.Возможно, вам также понадобится конструктор копирования из Point, который делает то же самое.

1 голос
/ 20 октября 2010

Чаще всего это делается с помощью конструктора преобразования:

Vec3(const Point& p) : x(p.x), y(p.y), z(p.z) {}

Это также разрешит назначение, которое вы хотите.

1 голос
/ 20 октября 2010

Я согласен с sheepsimulator в том, что оператор копирования должен иметь то же поведение, что и конструктор копирования.В соответствии с HIGH · INTEGRITY C ++ STANDARD MANUAL, вы должны реализовать явный оператор преобразования:

class Point { explicit operator Vec3() { return Vec3(this->x,this->y,this->z);  } };
1 голос
/ 20 октября 2010

Вы хотите это:

Vec3 & Vec3::operator =(const Point &a) 
{
x = a.x;
y = a.y;
z = a.z;
return *this;
}
  1. Назначение должно изменять этот объект, а не возвращать что-либо
  2. Возвращать ссылку на только что измененный объект
1 голос
/ 20 октября 2010

Оператор присваивания работает следующим образом.

Vec3.h:

Vec3& operator = (const Point &a);

Vec3.cpp:

Vec3& Vec3::operator = (const Point &a)
{
    x = a.x;
    y = a.y;
    z = a.z;
    return *this;
}

Обратите внимание, что вы модифицируете this объект и возвращаете неконстантную ссылку на него.

0 голосов
/ 20 октября 2010

Хм, здесь уже 6 ответов, и вы уже выбрали один, но самое простое и очевидное ИМХО отсутствует.

Vec3 &Vec3::operator =(Point a) // not const, return by reference
    {
        return *this = Vec3(a.x,a.y,a.z);
    }

Вот и все!Просто вставьте *this = и вернитесь по ссылке!Готово!

Я бы рекомендовал вместо этого реализовать конструктор преобразования.

0 голосов
/ 20 октября 2010

Есть несколько ответов, объясняющих, как делать то, что вы хотите, но я объясню, что происходит с вашим исходным кодом:

В C ++ (как в C) ваше назначение v = tp является выражением, а незаявление.Если вы пишете x = 1, вы можете написать y = (x = 1), потому что присваивание (x = 1) является выражением со значением 1. Когда вы переопределяете оператор присваивания в C ++, вы отвечаете за обе части: вы должны изменить thisВы должны вернуть значение выражения присваивания.Ваша оригинальная версия позаботилась только о возвращении значения выражения.Если бы вы написали Vec3 w = (v = tp), тогда w имел бы ожидаемое значение, тогда как v все равно было бы 0.

Другой способ выразить то же самое в C ++ - добавить operator Vec3 к вашему.Класс Point, так что вы можете использовать Point везде, где вы можете использовать Vec3.Еще лучше, вероятно, иметь один класс Vec3 и typedef Vec3 Point, потому что они в значительной степени идентичны.

0 голосов
/ 20 октября 2010

Почему бы просто не сделать это:

void Vec3::SetCoord(const Point& pnt)
{
    x = pnt.x;
    y = pnt.y;
    z = pnt.z;
}

ИЛИ ...

Создать новый перегруженный конструктор:

Vec3::Vec3(const Point& pnt)
{
    x = pnt.x;
    y = pnt.y;
    z = pnt.z;
}

Не требуется сумасшедший оператор приведения или оператор равенства,Я бы порекомендовал сделать один из этих способов, его, вероятно, проще всего поддерживать.


Чтобы получить приведенный выше синтаксис equals, нужно добавить оператор преобразования типов, но в Point:

class Point
{
     // ....

     operator Vec3()
     {
        return Vec3(this->x,this->y,this->z);
     }
};

Выполнение присваивания между двумя объектами подобным образом довольно забавно, не предполагая преобразования типов.Большинство классов ведут себя не так, как синтаксис.

Обратите внимание, что это может вызвать некоторую двусмысленность, и многие уважаемые люди на этом сайте, отвечающие на вопросы по C ++, скажут, что ответ с преобразованием типовможет вызвать всевозможные неприятные проблемы.Так что я бы избежал этого.

...