Antananarivu Для общего случая тут нельзя сказать, как более правильно, ибо когда речь идёт о перегруженных операторах, нельзя говорить за вообще любые случаи. Всё зависит от того, как именно и что именно перегружается. В контексте, когда при перегрузке интуитивный смысл операторов не меняется, можно сказать, что обе формы - и оригинальная, и твоя изменённая - эквивалентны.
Однако у меня будут возражения по самой форме реализации этой функциональности. Как-то не принято реализовывать методы класса путём заюзывания в них перегруженных операторов. Поясню. Перегруженный оператор ! возвращает значение. Скорее всего его прототип выглядит как
T3DMatrix operator!(const T3DMatrix&);. Или я не прав? Если нет, тогда это серьёзная ошибка проектирования. Далее, раз так, то этот оператор не обязан быть даже методом класса, ибо не меняет его внутренного состояния, а конструирует новый экземпляр. Раз так, то реализация оператора присваивания, который обязан быть методом класса и при этом полагается на неметод класса, выглядит просто странно. Обычно делают наоборот - делают методы класса, которые выполняют нужные действия, а перегруженные операторы реализуют с использованием этих методов. Но это всё не настолько критично, чтобы сказать, что это неправильно. Кривое проектирование - да. Но ошибочным оно-таки не является.
К слову сказать, могу перечислить проблемы проектирования
T3DVector-а:
public: T x,y,z; - открытые данные; тут без комментариев.
T3DVector(int); - на кой понадобился этот конструктор - совершенно непонятно.
int get_dim() const - то же самое. Интересно поглядеть на более общий
TxDVector , если он у автора вообще получится; я в этом сильно сомневаюсь, если судить по интерфейсу
T3DVector-а
template <class in> T3DVector(const T3DVector<in>&); - если автор считал, что этот шаблонный контруктор сойдёт за конструктор копии, то он неправ - не сойдёт. Как результат, компилятор попытается сгенерить тривиальный копирующий конструктор, если он ему понадобится.
template <class in> T3DVector<T>& operator =(const T3DVector<in>&) - тоже самое. Это не тот же оператор присваивания, который будет заюзан при присваивании одного экземпляра другому. Снова компилятор будет пытаться генерировать тривиальный оператор присваивания. Более того, этот шаблонный перегруженный оператор небезопасен по отношению к пользовательским исключениям.
Непонятно откуда взялась
::norm2(). Я её прототипа не увидел.
T3DVector<T>& operator +=(const T3DVector<T>&) и иже с ним - также небезопасны к исключениям.
assert(a != T()); внутри
T3DVector<T>& operator /=(const T3DVector<T>&) - совершенно лишняя строка, даже вредная.
void write(std::ostream&)const и
void read(std::istream&) - а я предпочитаю использовать UNICODEовые потоки. И что мне теперь делать? Кроме того, они спроектированы с нарушениями рекомендаций по разработке подобных методов. А
read() - так вообще неправильно написан.
__STL_TEMPLATE_NULL struct __type_traits<T3DFVector> и иже с ними - врут.
template <class T> std::istream& operator >> (std::istream&, T3DVector<T>&) - неверен. Даже новички такие ошибки редко допускают.
template <class T> inline const T3DVector<T> operator /(const T3DVector<T> a,const T) и иже с ним - константный параметр по значению... гм... я логику не осилил.
assert() внутри - аналогично уже сказанному.
template <class T> inline const bool operator == (const T3DVector<T>&,const T3DVector<T>&) - навязывает оператору сравнения самому разбираться с неточностью представления данных с плавающей точкой.
В общем, я бы поостерёгся пользоваться этим классом.
Abs62 В общем да. Но не совсем. Если быть совсем уж точным, то там говорится, что не гарантируется отсутствие незанятого пространства между элементами. Т.е. между x1, x2 и/или x3 могут быть пустоты. Для массивов же отсутствие пустот как раз гарантируется (это утверждение именно в этой цитате отсутствует, но присутствует в соответствующем разделе стандарта).