Russian Qt Forum

Программирование => С/C++ => Тема начата: qtkoder777 от Февраль 08, 2018, 16:31



Название: Перегрузка операторов при наследовании
Отправлено: qtkoder777 от Февраль 08, 2018, 16:31
Перехожу с самописных векторов на GLM.
Сейчас можно написать

Код
C++ (Qt)
Vector3D v1,v2;
Vector3D v3 = v1.Cross(v2).Normalized();

А в glm::vec3 так нельзя, хочу унаследоваться и добавить функции совместимости.

Код
C++ (Qt)
class Vec3 : public glm::dvec3
{
public:
Vec3(double _x = 0,double _y = 0,double _z = 0) : glm::dvec3(_x,_y,_z){}
inline Vec3 operator + (const Vec3 & p){return Vec3(x+p.x,y+p.y,z+p.z);}
inline Vec3 operator - (const Vec3 & p){return Vec3(x-p.x,y-p.y,z-p.z);}
inline Vec3 operator / (double c){return Vec3(x/c,y/c,z/c);}
inline Vec3 operator * (double c){return Vec3(x*c,y*c,z*c);}
inline Vec3 Normalized() const{glm::normalize(*this);}
inline double Length() const {return glm::length<double>(*this);}
inline Vec3 Cross(const Vec3 & p)const{return glm::cross(*this, p);}
};


На строку

Код
C++ (Qt)
D = (p2 - p1).Cross(p3 - p2).Normalized();

пишет ошибку
Код
C++ (Qt)
error C2039: 'Cross' : is not a member of 'glm::detail::tvec3<T>'
1>          with
1>          [
1>              T=glm::highp_float
1>    
     


Как так? Я перегрузил оператор - , он должен возвращать Vec3, а там есть Cross!


Название: Re: Перегрузка операторов при наследовании
Отправлено: Авварон от Февраль 08, 2018, 16:35
У вас оператор неконстантный, возможно в этом дело. В любом случае, применяется какой-то другой оператор, который возвращает базовый класс.
Вообще, бинарные операторы лучше делать свободными ф-иями, читайте майерса.


Название: Re: Перегрузка операторов при наследовании
Отправлено: qtkoder777 от Февраль 08, 2018, 17:03
У вас оператор неконстантный, возможно в этом дело. В любом случае, применяется какой-то другой оператор, который возвращает базовый класс.
Вообще, бинарные операторы лучше делать свободными ф-иями, читайте майерса.

Да, дело в этом, спасибо.
А можно ли вообще не перегружать операторы?
Я хочу чтоб они делали то же самое что в базовом классе. Тем более новых членов-данных нет.


Название: Re: Перегрузка операторов при наследовании
Отправлено: ViTech от Февраль 08, 2018, 17:48
А можно ли вообще не перегружать операторы?

Если операторы не перегружать, то и возвращать они будут экземпляры базового класса.
Вообще, в свежих стандартах С++ можно "использовать" конструкторы и операторы базового класса:
Код
C++ (Qt)
class Vec3 : public glm::dvec3
{
public:
using glm::dvec3::dvec3;
       using glm::dvec3::operator=;
       using glm::dvec3::operator-;
       ...
};
но в данном случае это не поможет.

Я хочу чтоб они делали то же самое что в базовом классе. Тем более новых членов-данных нет.

Можете попробовать вызывать операторы базового класса:
Код
C++ (Qt)
class Vec3 : public glm::dvec3
{
public:
   Vec3 operator + (const Vec3 & p) const {return static_cast<const glm::dvec3 &>(*this).operator+(p);}
};

Но лучше, действительно, может:
Вообще, бинарные операторы лучше делать свободными ф-иями, читайте майерса.


Название: Re: Перегрузка операторов при наследовании
Отправлено: Авварон от Февраль 08, 2018, 19:43

Но лучше, действительно, может:
Ну это скорее оффтоп, а вообще, интересно, как это сделать грамотно.


Название: Re: Перегрузка операторов при наследовании
Отправлено: qtkoder777 от Февраль 09, 2018, 10:08
Унаследоваться так и не удается.
Чего ему не хватает?

Код
C++ (Qt)
error C2440: '<function-style-cast>' : cannot convert from 'const Vec3' to 'double'
4>          No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

В кодах библиотеки показывает на
Код
C++ (Qt)
template <typename T>
template <typename U>
GLM_FUNC_QUALIFIER tvec3<T>::tvec3
(
U const & s
) :
x(value_type(s)),
y(value_type(s)),
z(value_type(s))
{}


Название: Re: Перегрузка операторов при наследовании
Отправлено: qtkoder777 от Февраль 09, 2018, 11:24
Конструктор копирования решил проблему
Код
C++ (Qt)
inline Vec3(const Vec3 & v) : glm::dvec3(v.x,v.y,v.z){}


Название: Re: Перегрузка операторов при наследовании
Отправлено: Igors от Февраль 09, 2018, 13:01
Вообще, бинарные операторы лучше делать свободными ф-иями, читайте майерса.
Не изучал  (так, смотрел мельком), но в данном случае все к месту
Код
C++ (Qt)
Vec3 n = (p2 - p1).Cross(p3 - p2).Normalized();
Vec3 n = ((p2 - p1) ^ (p3 - p2)).Normalized();
Vec3 n = Vec3::Cross(p2 - p1, p3 - p2).Normalized();
 
Второй и третий варианты не хуже, а лично мне поприятнее. Также обычно 2 варианта нормализации (с проверкой и без)


Название: Re: Перегрузка операторов при наследовании
Отправлено: Авварон от Февраль 10, 2018, 15:23
Вообще, бинарные операторы лучше делать свободными ф-иями, читайте майерса.
Не изучал  (так, смотрел мельком), но в данном случае все к месту

А зря, например, такой код не будет работать без бинарного оператора ну никак.
Код:
Vec3 v1;
glm::dvec3 v2;
auto v3 = (v2+v1).Normalized();