здравствуйте. кто-нить может мне пояснить, почему не получается сделать: Код (Text): Vector lerpVector(Vector &v1, Vector &v2, float t) { return v1*(1-t) + v2*t; } имея ввиду, что класс Vector определен след образом: Код (Text): class Vector { friend class Matrix; public: Vector(); Vector(float px, float py, float pz); Vector(Vector &example); ~Vector(); Vector crossProduct(Vector &vect); float dotProduct(Vector &vect); Vector operator + (Vector const &vect); Vector operator - (Vector const &vect); Vector operator += (Vector const &vect); Vector operator -= (Vector const &vect); Vector operator * (Matrix const &mat); Vector operator *= (Matrix const &mat); Vector operator * (const float &value); Vector operator *= (float const &value); Vector operator / (const float &value); bool operator == (Vector const &vect); void operator = (Vector const &vect); Vector normalize(); float length(); float x, y, z; float a; }; а сама реализация класса имеет вид: Код (Text): Vector::Vector() { x = y = z = 0.0f; } Vector::Vector(float px, float py, float pz) { x = px; y = py; z = pz; } Vector::Vector(Vector &example) { x = example.x; y = example.y; z = example.z; } Vector::~Vector() { } float Vector::length() { return (float)sqrt(x*x+y*y+z*z); } Vector Vector::normalize() { float l = length(); if (l==0) return Vector(0,0,0); x /= l; y /= l; z /= l; return Vector(x, y, z); } float Vector::dotProduct(Vector &vect) { return x*vect.x + y*vect.y + z*vect.z; } Vector Vector::crossProduct(Vector &vect) { float tx = y*vect.z-z*vect.y; float ty = x*vect.z-z*vect.x; float tz = x*vect.y-y*vect.x; return Vector(tx, ty, tz); } Vector Vector::operator + (Vector const &vect) { float tx, ty, tz; tx = x + vect.x; ty = y + vect.y; tz = z + vect.z; return Vector(tx, ty, tz); } Vector Vector::operator - (Vector const &vect) { float tx, ty, tz; tx = x - vect.x; ty = y - vect.y; tz = z - vect.z; return Vector(tx, ty, tz); } Vector Vector::operator += (Vector const &vect) { x += vect.x; y += vect.y; z += vect.z; return Vector(x, y, z); } Vector Vector::operator -= (Vector const &vect) { x -= vect.x; y -= vect.y; z -= vect.z; return Vector(x, y, z); } Vector Vector::operator * (Matrix const &mat) { float tx, ty, tz; tx = mat.data[0][0]*x + mat.data[0][1]*y + mat.data[0][2]*z; ty = mat.data[1][0]*x + mat.data[1][1]*y + mat.data[1][2]*z; tz = mat.data[2][0]*x + mat.data[2][1]*y + mat.data[2][2]*z; return Vector(tx, ty, tz); } Vector Vector::operator *= (Matrix const &mat) { float tx, ty, tz; tx = mat.data[0][0]*x + mat.data[0][1]*y + mat.data[0][2]*z; ty = mat.data[1][0]*x + mat.data[1][1]*y + mat.data[1][2]*z; tz = mat.data[2][0]*x + mat.data[2][1]*y + mat.data[2][2]*z; x = tx; y = ty; z = tz; return Vector(x, y, z); } Vector Vector::operator * (float const &value) { float tx, ty, tz; tx = x * value; ty = y * value; tz = z * value; return Vector(tx, ty, tz); } Vector Vector::operator *= (float const &value) { x *= value; y *= value; z *= value; return Vector(x, y, z); } Vector Vector::operator / (float const &value) { if(value <= 0) return Vector(0.0f, 0.0f, 0.0f); float tx, ty, tz; tx = x / value; ty = y / value; tz = z / value; return Vector(tx, ty, tz); } bool Vector::operator == (Vector const &vect) { if (x == vect.x && y == vect.y && z == vect.z) return true; else return false; } void Vector::operator = (Vector const &vect) { x = vect.x; y = vect.y; z = vect.z; } Dev-C++ 4.9.9.2 ругается: меня уже подобные финты ушами этого Dev-C++ просто добивают. причем он так кричит не только на мой код, но и вообще на код от стороннего производителя (т.е. безбажный по идее). типа, компилер ждет что я в конструктор передам значение по ссылке, а не по значению, так? если да, то как мне это сделать. буду признателен если поясните что к чему здесь. спасибо!
У тебя конструктов вектора только по ссылке, а автоматический объект, создаваемый на возврате функции требует конструктора по значению. Если не ошибся.
IceStudent, спасибо за пояснения. действительно, конструктор вектора по ссылке. вся заковырка в том, что почему-то не получается добавить конструктор у вектора по значению, по кр мере компилер ругается на такой код: Код (Text): Vector::Vector(Vector example) { x = example.x; y = example.y; z = example.z; } может это только Dev-C++ ругается (на MSVC у меня сейчас нет возможности протестить). вопрос первый: (не)правилен ли этот код? вопрос второй: как тогда вообще должен выглядеть конструктор вектора, инициализируемый другим вектором? большое спасибо за разъяснения, а то я вообще не пойму эти тонкости уже
varnie Не, так нельзя - иначе будет рекурсия в конструкторах. Сейчас посмотрю. Вот, рабочий пример. Реализованы только операторы + и +=, что позволяет сделать почти твоё: Код (Text): Vec foo(Vec& v1, Vec& v2, int f){ return (v1+(1-f)) + (v2 + f); } Реализация: Код (Text): template<typename T> class Vec_t { T x,y,z; public: // default Vec_t(){ x = y = z = T(); } ~Vec_t(){} // init explicit Vec_t(const T& x, const T& y, const T& z){ this->x = x; this->y = y; this->z = z; } // copy constructor Vec_t(const Vec_t& v){ x = v.x; y = v.y; z = v.z; } // assignment Vec_t& operator=(const Vec_t& v){ x = v.x; y = v.y; z = v.z; return *this; } // math Vec_t operator+(const Vec_t& v){ Vec_t vv(x,y,z); return vv += v; } Vec_t& operator+=(const Vec_t& v){ x += v.x; y += v.y; z += v.z; return *this; } Vec_t operator+(const T& f){ Vec_t vv(x,y,z); return vv += f; } Vec_t& operator+=(const T& f){ x += f; y += f; z += f; return *this; } // ... }; typedef Vec_t<int> Vec;
IceStudent, а у меня при твоей реализации не считает твой вариант метода foo. компилер выдает: ps: может мне ст0ит перейти на серьезный компилер а-ля MSVC ?
varnie Я не уверен насчёт соответствия стандарту своего кода. Может пропустил что-то, на что vc не обращает внимания.
IceStudent вооще-то можно попробовать именно для соответствия стандарту понаписывать везде, где только можно тип параметра const Vector&, так как просто Vector& по стандарту не разрешает преобразования типов и использования временных переменных, так что дело может быть именно в этом. Кстати запись Vector const& особого значения не имеет, ссылка всегда является константным объектом.
С каких это пор? Ссылка сама по себе не является объектом. Код (Text): void f(int& i){ i++; } void f2(const int& i){ i++; } Может, ты имел ввиду вот это? Код (Text): void f3(int& const i){ i++; }
Ustus, попробовал ваш совет, но теперь в вышеописанной ф-ции компилер ругается вот как: т.е. раз v1 был передан как const Vec&. то его и не получится поменять. вот компилер и ругается, т.к. в части v1+(1-f) проивзодится попытка изменить переданный v1. что ж делать? добавлено: а, не. теперь все норм. я в классе в методах параметры объявил как const Vec_t& v, а в этой ф-ции foo, выше которая передаю их как просто Vector &
varnie Кстати, по поводу перегрузки операторов и решения для матриц: http://www.parashift.com/c++-faq-lite/operator-overloading.html
varnie чтобы не ругался, сам оператор надо объявить как константный: Vector Vector::operator +(const Vector&) const или вообще задать его не как член класса, что позволит применять неявные преобразования к первому аргументу: Vector operator +(const Vector&, const Vector&)
охх, и намаялся я с кодом сторонним. это все оттуда запары эти)). посему, еще вдогонку вопрос один - а можно ли как-нибудь перегрузить оператор, скажем operator *, чтобы можно было делать так: Код (Text): int x = 1; Vector v1 = Vector(0,0,0); //имеется вектор Vector v2 = x*v1; //по идее надо бы Vector v2 = v1*x т.е. пробую не вектор умножить на число, а число умножить на вектор. компилер мой ругается (и это, имха, правильно он ругается). но тогда почему в этом коде, который я скачал и с которым ковыряюсь, присутствует подобное выражение? простите, если я вас уже достал
Сейчас не помню нужного решения, но вот этакий workaround: Код (Text): template<typename T> Vec_t<T> operator+(const T& f, const Vec_t<T>& v) { Vec_t<T> vv(v); return vv += f; } Собственно, это не обход - так и нужно. Другое, общее, решение основывается на том, что можно создать Vec_t<T> из T и тогда уже применить обычное сложение. Но здесь это будет накладно, поэтому остаётся только решение, которое я и привёл.
varnie Вай, как это трудно... А давай попробуем вот так: Код (Text): Vector operator *(const int i, const Vector & v) { return v*i; } Конечно, чтобы это работало, нужно: 1) иметь Vector::operator *(const Vector &v, const int i) - ну это уже есть, я так понимаю 2) операция умножения должна быть коммутативна - что в этом случае так и есть
maksym, на этот метод компилер выдает ошибку: и еще: почему-то линкер ругается очень много раз на: в коде, не смотря на то, что эти методы перегрузки операторов у меня в реализации класса Vec_t есть.
varnie У вас, батенька, вот где ошибка (понятное дело, навеяна моим неточным цитированием): Поскольку оператор принадлежит классу, явно его первый параметр не объявляется. Другими словами, ваш оператор класса должен выглядеть вот так: Код (Text): Vec_t<T> Vec_t<T>::operator*(const int i) Что касается ошибок линкера, это нужно на сигнатуры смотреть ближе. Например, где именно стоит const. В любом случае, фокус в том, чтобы переставить местами аргументы во внеклассовом операторе так, чтобы вызвался нужный внутриклассовый оператор.
...Дабы не создавать новую тему; а в этом коде где ошибка может быть? Компилятор говорит то же самое, то есть: Код (Text): #include <vector> using namespace std; int main () { std::vector<int> myvector; return 0; } [Linker error] undefined reference to `__gxx_personality_v0' ...А предыстория всего этого дела такова, я с DEV C++ 4.9.9.2 ГОРЯ НЕ ЗНАЛ, пока несколько дней назад не решил пойти в ногу со временем и поставил mingw годичной давности, g++ 4.5.0 (до этого был g++ 3.4.2, аж 2004 года) ну пошли глюки разные и это один из них только.