бажит Dev-C++ или что?

Тема в разделе "WASM.ZEN", создана пользователем varnie, 15 янв 2007.

  1. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    здравствуйте.

    кто-нить может мне пояснить, почему не получается сделать:

    Код (Text):
    1. Vector lerpVector(Vector &v1, Vector &v2, float t)
    2. {
    3.    return v1*(1-t) + v2*t;
    4. }
    имея ввиду, что класс Vector определен след образом:

    Код (Text):
    1. class Vector
    2.     {
    3.         friend class Matrix;   
    4.  
    5.         public:
    6.             Vector();
    7.             Vector(float px, float py, float pz);
    8.             Vector(Vector &example);
    9.             ~Vector();
    10.  
    11.             Vector crossProduct(Vector &vect);
    12.             float dotProduct(Vector &vect);
    13.  
    14.             Vector operator + (Vector const &vect);
    15.             Vector operator - (Vector const &vect);
    16.             Vector operator += (Vector const &vect);
    17.             Vector operator -= (Vector const &vect);
    18.  
    19.             Vector operator * (Matrix const &mat);
    20.             Vector operator *= (Matrix const &mat);
    21.             Vector operator * (const float &value);
    22.             Vector operator *= (float const &value);
    23.             Vector operator / (const float &value);
    24.  
    25.             bool operator == (Vector const &vect);
    26.             void operator = (Vector const &vect);
    27.            
    28.             Vector normalize();
    29.             float length();
    30.  
    31.             float x, y, z;
    32.  
    33.             float a;   
    34.     };
    а сама реализация класса имеет вид:

    Код (Text):
    1. Vector::Vector()
    2. {
    3.     x = y = z = 0.0f;
    4. }
    5. Vector::Vector(float px, float py, float pz)
    6. {
    7.     x = px;
    8.     y = py;
    9.     z = pz;
    10. }
    11. Vector::Vector(Vector &example)
    12. {
    13.     x = example.x;
    14.     y = example.y;
    15.     z = example.z;
    16. }
    17.  
    18. Vector::~Vector()
    19. {
    20.  
    21. }
    22.  
    23. float Vector::length()
    24. {
    25.     return (float)sqrt(x*x+y*y+z*z);
    26. }
    27.  
    28. Vector Vector::normalize()
    29. {
    30.     float l = length();
    31.     if (l==0)
    32.         return Vector(0,0,0);
    33.     x /= l;
    34.     y /= l;
    35.     z /= l;
    36.  
    37.     return Vector(x, y, z);
    38. }
    39.  
    40. float Vector::dotProduct(Vector &vect)
    41. {
    42.     return x*vect.x + y*vect.y + z*vect.z;
    43. }
    44.  
    45. Vector Vector::crossProduct(Vector &vect)
    46. {
    47.     float tx = y*vect.z-z*vect.y;
    48.     float ty = x*vect.z-z*vect.x;
    49.     float tz = x*vect.y-y*vect.x;
    50.     return Vector(tx, ty, tz);
    51. }
    52. Vector Vector::operator + (Vector const &vect)
    53. {
    54.     float tx, ty, tz;
    55.     tx = x + vect.x;
    56.     ty = y + vect.y;
    57.     tz = z + vect.z;
    58.  
    59.     return Vector(tx, ty, tz);
    60. }
    61. Vector Vector::operator - (Vector const &vect)
    62. {
    63.     float tx, ty, tz;
    64.     tx = x - vect.x;
    65.     ty = y - vect.y;
    66.     tz = z - vect.z;
    67.     return Vector(tx, ty, tz);
    68. }
    69. Vector Vector::operator += (Vector const &vect)
    70. {
    71.     x += vect.x;
    72.     y += vect.y;
    73.     z += vect.z;
    74.  
    75.     return Vector(x, y, z);
    76. }
    77. Vector Vector::operator -= (Vector const &vect)
    78. {
    79.     x -= vect.x;
    80.     y -= vect.y;
    81.     z -= vect.z;
    82.  
    83.     return Vector(x, y, z);
    84. }
    85. Vector  Vector::operator * (Matrix const &mat)
    86. {
    87.     float tx, ty, tz;
    88.     tx = mat.data[0][0]*x + mat.data[0][1]*y + mat.data[0][2]*z;
    89.     ty = mat.data[1][0]*x + mat.data[1][1]*y + mat.data[1][2]*z;
    90.     tz = mat.data[2][0]*x + mat.data[2][1]*y + mat.data[2][2]*z;
    91.     return Vector(tx, ty, tz);
    92. }
    93.  
    94. Vector  Vector::operator *= (Matrix const &mat)
    95. {
    96.     float tx, ty, tz;
    97.     tx = mat.data[0][0]*x + mat.data[0][1]*y + mat.data[0][2]*z;
    98.     ty = mat.data[1][0]*x + mat.data[1][1]*y + mat.data[1][2]*z;
    99.     tz = mat.data[2][0]*x + mat.data[2][1]*y + mat.data[2][2]*z;
    100.  
    101.     x = tx;
    102.     y = ty;
    103.     z = tz;
    104.     return Vector(x, y, z);
    105. }
    106. Vector Vector::operator * (float const &value)
    107. {
    108.     float tx, ty, tz;
    109.     tx = x * value;
    110.     ty = y * value;
    111.     tz = z * value;
    112.  
    113.     return Vector(tx, ty, tz);
    114. }
    115. Vector Vector::operator *= (float const &value)
    116. {
    117.     x *= value;
    118.     y *= value;
    119.     z *= value;
    120.  
    121.     return Vector(x, y, z);
    122. }
    123. Vector Vector::operator / (float const &value)
    124. {
    125.     if(value <= 0) return Vector(0.0f, 0.0f, 0.0f);
    126.  
    127.     float tx, ty, tz;
    128.     tx = x / value;
    129.     ty = y / value;
    130.     tz = z / value;
    131.  
    132.     return Vector(tx, ty, tz);
    133. }
    134. bool Vector::operator == (Vector const &vect)
    135. {
    136.     if (x == vect.x && y == vect.y && z == vect.z)
    137.         return true;
    138.     else return false;
    139.  
    140. }
    141.  
    142. void Vector::operator = (Vector const &vect)
    143. {
    144.     x = vect.x;
    145.     y = vect.y;
    146.     z = vect.z;
    147. }
    Dev-C++ 4.9.9.2 ругается:

    меня уже подобные финты ушами этого Dev-C++ просто добивают. причем он так кричит не только на мой код, но и вообще на код от стороннего производителя (т.е. безбажный по идее). типа, компилер ждет что я в конструктор передам значение по ссылке, а не по значению, так? если да, то как мне это сделать.
    буду признателен если поясните что к чему здесь. спасибо!
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    У тебя конструктов вектора только по ссылке, а автоматический объект, создаваемый на возврате функции требует конструктора по значению. Если не ошибся.
     
  3. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    IceStudent,
    спасибо за пояснения. действительно, конструктор вектора по ссылке.
    вся заковырка в том, что почему-то не получается добавить конструктор у вектора по значению, по кр мере компилер ругается на такой код:
    Код (Text):
    1. Vector::Vector(Vector example)
    2. {
    3.    x = example.x;
    4.    y = example.y;
    5.    z = example.z;
    6. }
    может это только Dev-C++ ругается (на MSVC у меня сейчас нет возможности протестить).

    вопрос первый: (не)правилен ли этот код?
    вопрос второй: как тогда вообще должен выглядеть конструктор вектора, инициализируемый другим вектором?

    большое спасибо за разъяснения, а то я вообще не пойму эти тонкости уже:dntknw:
     
  4. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    varnie
    Не, так нельзя - иначе будет рекурсия в конструкторах. Сейчас посмотрю.

    Вот, рабочий пример. Реализованы только операторы + и +=, что позволяет сделать почти твоё:
    Код (Text):
    1. Vec foo(Vec& v1, Vec& v2, int f){
    2.     return (v1+(1-f)) + (v2 + f);
    3. }
    Реализация:
    Код (Text):
    1. template<typename T>
    2. class Vec_t
    3. {
    4.     T x,y,z;
    5. public:
    6.     // default
    7.     Vec_t(){
    8.         x = y = z = T();
    9.     }
    10.     ~Vec_t(){}
    11.     // init
    12.     explicit Vec_t(const T& x, const T& y, const T& z){
    13.         this->x = x;
    14.         this->y = y;
    15.         this->z = z;
    16.     }
    17.     // copy constructor
    18.     Vec_t(const Vec_t& v){
    19.         x = v.x;
    20.         y = v.y;
    21.         z = v.z;
    22.     }
    23.     // assignment
    24.     Vec_t& operator=(const Vec_t& v){
    25.         x = v.x;
    26.         y = v.y;
    27.         z = v.z;
    28.         return *this;
    29.     }
    30.    
    31.     // math
    32.     Vec_t operator+(const Vec_t& v){
    33.         Vec_t vv(x,y,z);
    34.         return vv += v;
    35.     }
    36.     Vec_t& operator+=(const Vec_t& v){
    37.         x += v.x;
    38.         y += v.y;
    39.         z += v.z;
    40.         return *this;
    41.     }
    42.     Vec_t operator+(const T& f){
    43.         Vec_t vv(x,y,z);
    44.         return vv += f;
    45.     }
    46.     Vec_t& operator+=(const T& f){
    47.         x += f;
    48.         y += f;
    49.         z += f;
    50.         return *this;
    51.     }
    52.     // ...
    53. };
    54.  
    55. typedef Vec_t<int> Vec;
     
  5. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    IceStudent,
    а у меня при твоей реализации не считает твой вариант метода foo.

    компилер выдает:
    ps: может мне ст0ит перейти на серьезный компилер а-ля MSVC ?
     
  6. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    varnie
    Я не уверен насчёт соответствия стандарту своего кода. Может пропустил что-то, на что vc не обращает внимания.
     
  7. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Не знаю. VC 7.1 и 8.0 компилируют без замечаний, как и gcc 3.4.2 (никсовый и виндовый).
     
  8. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    IceStudent
    вооще-то можно попробовать именно для соответствия стандарту понаписывать везде, где только можно тип параметра const Vector&, так как просто Vector& по стандарту не разрешает преобразования типов и использования временных переменных, так что дело может быть именно в этом. Кстати запись Vector const& особого значения не имеет, ссылка всегда является константным объектом.
     
  9. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    С каких это пор? Ссылка сама по себе не является объектом.

    Код (Text):
    1. void f(int& i){
    2.   i++;
    3. }
    4.  
    5. void f2(const int& i){
    6.   i++;
    7. }
    Может, ты имел ввиду вот это?
    Код (Text):
    1.  void f3(int& const i){
    2.   i++;
    3. }
     
  10. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    Ustus,
    попробовал ваш совет, но теперь в вышеописанной ф-ции компилер ругается вот как:

    т.е. раз v1 был передан как const Vec&. то его и не получится поменять. вот компилер и ругается, т.к. в части v1+(1-f) проивзодится попытка изменить переданный v1.

    что ж делать?

    добавлено: а, не. теперь все норм. я в классе в методах параметры объявил как const Vec_t& v, а в этой ф-ции foo, выше которая передаю их как просто Vector &
     
  11. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Точно. Правда, у gcc тяжёлые дни:
    Впрочем, g++ взял.
     
  12. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    varnie
    Кстати, по поводу перегрузки операторов и решения для матриц: http://www.parashift.com/c++-faq-lite/operator-overloading.html
     
  13. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    varnie
    чтобы не ругался, сам оператор надо объявить как константный:
    Vector Vector::operator +(const Vector&) const
    или вообще задать его не как член класса, что позволит применять неявные преобразования к первому аргументу:
    Vector operator +(const Vector&, const Vector&)
     
  14. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Ustus
    Да нет, это он в foo константы добавил.
     
  15. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    охх, и намаялся я с кодом сторонним. это все оттуда запары эти)).
    посему, еще вдогонку вопрос один - а можно ли как-нибудь перегрузить оператор, скажем operator *, чтобы можно было делать так:

    Код (Text):
    1. int x = 1;
    2. Vector v1 = Vector(0,0,0); //имеется вектор
    3. Vector v2 = x*v1; //по идее надо бы Vector v2 = v1*x
    т.е. пробую не вектор умножить на число, а число умножить на вектор.
    компилер мой ругается (и это, имха, правильно он ругается).
    но тогда почему в этом коде, который я скачал и с которым ковыряюсь, присутствует подобное выражение?

    простите, если я вас уже достал:)
     
  16. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Сейчас не помню нужного решения, но вот этакий workaround:
    Код (Text):
    1. template<typename T>
    2. Vec_t<T> operator+(const T& f, const Vec_t<T>& v)
    3. {
    4.     Vec_t<T> vv(v);
    5.     return vv += f;
    6. }
    Собственно, это не обход - так и нужно. Другое, общее, решение основывается на том, что можно создать Vec_t<T> из T и тогда уже применить обычное сложение. Но здесь это будет накладно, поэтому остаётся только решение, которое я и привёл.
     
  17. maksym

    maksym New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2005
    Сообщения:
    4
    Адрес:
    United Kingdom
    varnie
    Вай, как это трудно... А давай попробуем вот так:

    Код (Text):
    1. Vector operator *(const int i, const Vector & v)
    2. {
    3.   return v*i;
    4. }
    Конечно, чтобы это работало, нужно:

    1) иметь Vector::operator *(const Vector &v, const int i) - ну это уже есть, я так понимаю
    2) операция умножения должна быть коммутативна - что в этом случае так и есть
     
  18. varnie

    varnie New Member

    Публикаций:
    0
    Регистрация:
    2 янв 2005
    Сообщения:
    1.785
    maksym,
    на этот метод компилер выдает ошибку:
    и еще:
    почему-то линкер ругается очень много раз на:
    в коде, не смотря на то, что эти методы перегрузки операторов у меня в реализации класса Vec_t есть.
     
  19. maksym

    maksym New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2005
    Сообщения:
    4
    Адрес:
    United Kingdom
    varnie
    У вас, батенька, вот где ошибка (понятное дело, навеяна моим неточным цитированием):

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

    Другими словами, ваш оператор класса должен выглядеть вот так:

    Код (Text):
    1. Vec_t<T> Vec_t<T>::operator*(const int i)
    Что касается ошибок линкера, это нужно на сигнатуры смотреть ближе. Например, где именно стоит const.

    В любом случае, фокус в том, чтобы переставить местами аргументы во внеклассовом операторе так, чтобы вызвался нужный внутриклассовый оператор.
     
  20. amvoz

    amvoz Member

    Публикаций:
    0
    Регистрация:
    12 ноя 2008
    Сообщения:
    653
    ...Дабы не создавать новую тему; а в этом коде где ошибка может быть? Компилятор говорит то же самое, то есть:
    Код (Text):
    1. #include <vector>
    2. using namespace std;
    3. int main () {
    4.  std::vector<int> myvector;
    5.  return 0;
    6. }
    [Linker error] undefined reference to `__gxx_personality_v0'

    ...А предыстория всего этого дела такова, я с DEV C++ 4.9.9.2 ГОРЯ НЕ ЗНАЛ, пока несколько дней назад не решил пойти в ногу со временем и поставил mingw годичной давности, g++ 4.5.0 (до этого был g++ 3.4.2, аж 2004 года) ну пошли глюки разные и это один из них только.