операторы в C++(IDE - QTcreator 4)

IDE, VCS и прочее

Модератор: Модераторы разделов

Ответить
Аватара пользователя
voipp
Сообщения: 57
ОС: openSUSE 11.2

операторы в C++(IDE - QTcreator 4)

Сообщение voipp »

программирую в Qtcreator 4. Написал вот такие операторы -

Код: Выделить всё

CVector& CVector::operator / (CVector &v){
    if((v.getSize()<=4)&&(v.getSize()>=3)){
    CVector vec(v.getSize());//создание нового вектора равного по длине v
    vec=v;
    vec[0]=this->operator [](1)*v[2]-this->operator [](2)*v[1];//доступ к элементу вектора
    vec[1]=this->operator [](2)*v[0]-this->operator [](0)*v[2];
    vec[2]=this->operator [](0)*v[1]-this->operator [](1)*v[0];
    return vec;
};

};

CVector CVector::operator +(const CVector &v) const
{
  CVector res(*this);//в новый вектор записывается вектор this
  for (unsigned i = 0; i < res.size; i++)
    res[i] = res[i] + v[i];//доступ к элементу вектора
  return res;
}


а вот строчка для вычесления -

Код: Выделить всё

normal=(o[i]/o[i+1]) + (o[13]/o[i]);//o[] и normal вектора

При отладке курсор останавливается на строке - res[i] = res[i] + v[i];
и отказывается дальше работать.А в режиме релиз выдается сообщение что работа неожиданно завершилась.

Вот что выдает еще отладчик -
&"warning: GDB: Failed to set controlling terminal: \320\235\320\265\320\264\320\276\320\277\321\203\321\201\321\202\320\270\320\274\321\213\320\271 \320\260\321\200\320\263\321\203\320\274\320\265\320\275\321\202\n"

ошибка возникла после добавления оператора / до этого все работало без ошибок
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: операторы в C++(IDE - QTcreator 4)

Сообщение NickLion »

Векторы o[] какую размерность имеют? Все одну?
Зачем в векторном произведении vec=v;?
Спасибо сказали:
Аватара пользователя
voipp
Сообщения: 57
ОС: openSUSE 11.2

Re: операторы в C++(IDE - QTcreator 4)

Сообщение voipp »

vec=v просто у меня 4 элемент массива у них совпадает это нужно для комп графики.а размерности o[i] - CVector
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: операторы в C++(IDE - QTcreator 4)

Сообщение NickLion »

voipp писал(а):
28.11.2009 15:46
а размерности o[i] - CVector

У всех 4 элемента?
o[13] - такой элемент существует?
Если да, то давайте больше кода, причины не понятны.

Дошло!
У вас оператор / возвращает ссылку на внутреннюю переменную! Этого делать нельзя, потому что переменная будет уничтожена и ссылка будет вести на левые данные.
Спасибо сказали:
Аватара пользователя
voipp
Сообщения: 57
ОС: openSUSE 11.2

Re: операторы в C++(IDE - QTcreator 4)

Сообщение voipp »

о! У меня всегда проблемы с этими ссылками и указателями.
Давайте разберемся раз и навсегда-
1)

Код: Выделить всё

int func(int arg)
эта функция принимающая аргумет копирует его колдует над этой копией и потом возвращает эту копию причем изначальная переданная переменная не изменяется
2)

Код: Выделить всё

void func(int& arg)
получает адрес(последоавтельность цифр по окторой она может переменную) переходит оп адресу, колдует над переменной и завершается.При этом после этого в переменной другое значение.Что бы получить значение переменной в теле функции нужно просто написать arg
3)

Код: Выделить всё

void func(int* arg)
тоже самое что и 2) но обращение к переменной происходит иначе -*arg
4)

Код: Выделить всё

int& func()
{int *arg или int& arg;.....return arg}
я создал указатель(тоесть переменную в которой адрес числа) а потом этот указатель возвратил
5)

Код: Выделить всё

int* func()
{int *arg  или int &arg;......return arg
тоже самое что и в 4)
Получется едиственное отличие символов & и * только в 2) и 3) а так они одно и тоже - хранят адрес переменной.
Я прав?
И почему тогда в операторе + создав внутреннюю переменную мы ее возвращаем а она оказывается не пуста.Или может он возвращает копию этой внутренней переменной?
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: операторы в C++(IDE - QTcreator 4)

Сообщение RasenHerz »

не лучше ли было сделать так?

Код: Выделить всё

class Vector{
   /**
       ....
   **/

   friend const Vector& operator+(const Vector&, const Vector&);
   friend const Vector& operator=(Vector&, const Vector&);

};
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: операторы в C++(IDE - QTcreator 4)

Сообщение NickLion »

2 voipp
Ссылка - это почти то же, что и указатель, за исключением:
1) ссылка должна инициализироваться при создании
2) не может быть "переуказана"
3) не требует явного разыменования
За исключением 3 пункта, ссылка идентична константному указателю (<type>* const).

В случае возврата объекта, а не ссылки, происходит копирование. Поэтому в случае "+" - всё нормально.

2 RasenHerz
Не лучше, ссылка всё-равно будет ссылаться на несуществующие данные.


В обоих случаях выдается предупреждение компилятором: warning: reference to local variable '....' returned.
Так что voipp, не пропускайте мимо предупреждения.
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: операторы в C++(IDE - QTcreator 4)

Сообщение RasenHerz »

NickLion писал(а):
29.11.2009 20:33
Не лучше, ссылка всё-равно будет ссылаться на несуществующие данные.

Что за глупости, все будет существовать:

Код: Выделить всё

Vector a = o[i]/o[i+1];
Vector b = o[13]/o[i];
Vector c = a + b;//вызываем operator+, и результат отправляем в operator=; результат от operator+ еще находится выше по стеку, так что данные верные

Так что все должно прекрасно работать, единственное что надо поправить еще:

Код: Выделить всё

friend const Vector& operator/(Vector&, const Vector&);


P.S. правда надо будет хорошенько подумать где возвращать Vector&, a где const Vector&.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: операторы в C++(IDE - QTcreator 4)

Сообщение NickLion »

RasenHerz писал(а):
29.11.2009 21:37
Что за глупости, все будет существовать:

Не глупости. Ничего существовать уже не будет.

Смотрите:

Код: Выделить всё

#include <stdio.h>

class X {
public:
    X() {
        printf( "Construction of %p\n", this );
        z = 0;
    }
    ~X() {
        printf( "Destruction of %p\n", this );
        z = 7;
    }

    int f() const {
        printf( "Inside f() of %p\n", this );
        return z;
    }

    friend const X& ff();

public:
    int z;
};

const X& ff() {
    X x;
    return x;
}

int main( int argc, char *argv[] ) {
    printf( "%d", ff().f() );
    return 0;
}


Вывод получим:

Код: Выделить всё

Construction of 0028FF1C
Destruction of 0028FF1C
Inside f() of 0028FF1C
7


Т.е. метод f() будет вызван для УЖЕ уничтоженного объекта, что видно по порядку вывода и возвращенному значению.
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: операторы в C++(IDE - QTcreator 4)

Сообщение RasenHerz »

сорри, действительно сглупил, поправлюсь:

Код: Выделить всё

friend Vector operator+(const Vector&, const Vector&);
const Vector& operator=(const Vector&);
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: операторы в C++(IDE - QTcreator 4)

Сообщение NickLion »

RasenHerz писал(а):
30.11.2009 06:58

Код: Выделить всё

friend Vector operator+(const Vector&, const Vector&);
const Vector& operator=(const Vector&);

Разрешите еще раз поправлю? :blush:
Для присваивания возврат константной ссылки не нужен, лучше просто ссылку. Допустим передать в функцию по неконстантной ссылке сразу с присваиванием f(a=b);. Или запись вида (a=b)+=c;.
Спасибо сказали:
Аватара пользователя
RasenHerz
Сообщения: 1341
ОС: Arch Linux amd64

Re: операторы в C++(IDE - QTcreator 4)

Сообщение RasenHerz »

NickLion писал(а):
30.11.2009 07:31
Разрешите еще раз поправлю? :blush:
Для присваивания возврат константной ссылки не нужен, лучше просто ссылку. Допустим передать в функцию по неконстантной ссылке сразу с присваиванием f(a=b);. Или запись вида (a=b)+=c;.

Я отношу это к разделу "на вкус и цвет" =) С таким оператором = допускается обход только справа налево (код вроде (a = b) = c; я считаю диким), да и ссылки я стараюсь как можно чаще передавать константные. Наверное, практически всегда единственным оператором возвращающим неконстантную ссылку у меня является << =)
Спасибо сказали:
Ответить