Страница 1 из 3

хе хе или пофлеймим в понедельнег :)

Добавлено: 19 мар 2007, 11:16
aissp
дано

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

class qq {
public:
...
qq& operator=(const qq& );
qq(size_t size) : size_(size) { ptr_ = new char[size] ;} //bla bla bla...
qq(const qq& cQ) {....};
...
private:
char* ptr_;
size_t size_;
};

qq& operator=(const qq& qRight) {
    if(this == &qRight} return *this;
    delete[] ptr;
    size_=qRight.size_;
    ptr_ = new char[size_];
    memcpy(ptr_, qRight.ptr_, size_);
    return *this;
};

а теперь вопрос - что тут плохо и можно ли ето поправить? Имеется ввиду только оператор присваивания, все остальное только для обрисовки ситуации

Re: хе хе или пофлеймим в понедельнег :)

Добавлено: 19 мар 2007, 11:17
(Alex)
Я не уверен, но наверно на Java было-бы круче... :-)

Добавлено: 19 мар 2007, 11:20
aissp
Ето 5 :lol:

Re: хе хе или пофлеймим в понедельнег :)

Добавлено: 19 мар 2007, 11:34
ajkj3em
copy constructora net
size_t is unsigned

if(this == &qRight} return *this;

Добавлено: 19 мар 2007, 11:42
aissp
О да тут ен в бровь а в глаз. Возраженья принимаются. Копи контсруктор добавляем ошипки поправляем. Проблема стилл екзист.

Проблема что будет если в операторе = возникнет исключение при запросе на новую память? Разница с конструкторами в том - что обхек уже существует, а после исключения он продолжает существовать но безнадежно испорчен... Вопрос что делать?:)

ДА там ща поправлю а то стыдно

Добавлено: 19 мар 2007, 11:59
ajkj3em
поменять определение инварианта для етого класса,
поставить try-catch, поймать исключение и все такое

либо запретить оператор присваивания в целом, сделав его private

вто в теории. а на практике - забить нах :)

Добавлено: 19 мар 2007, 12:03
aissp
На практике согласен видимо :) А так есть очень изяшное решение:

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

...
private:
void swap(qq& l, qq& r) throw();
};

qq& operator=(const qq& qRight) { 
    qq temp = qRight;
    swap(*this, temp); 
    return *this;
}; 


Добавлено: 19 мар 2007, 14:27
sz
Тем орлам, которые придумали, что new должен швыряться эксепшенами вместо нормального возвращения нуля, я бы выбил глаз.
Бьешься тут за оптимальный код и вдруг приходят орлы и такое в стандарт пишут...

Знаете что. Я пожалуй погорячился.
Оба глаза надо выбить.

Добавлено: 19 мар 2007, 14:41
(Alex)
Не используй такие классы, насильно же не заставляют...

Добавлено: 19 мар 2007, 14:58
aissp
Пральные пасаны всегда берегут свое зрение и поетому придумывают разные вещи. Конкретно для нью они придумали целых две:
1. new(notrhow) возвратит чисто нуль и не кинет ни в кого ексепшеном а также
2. new_handler set_new_handler(new_handler )
в случае проблемы н.ю будет вызывать ету функцию, более того если не предусмотреть выхода он ее будет до посинения вызывать

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

new(...) {
    while(1) {
       //try to get memory
      if(success)
           return memory;
      new_handler hndl = get_new_handler(0);
      if(hndl) (*hndl)();
      else {
         if(nothrow) return;
         throw bad_alloc();
      }
    }
}

типа такого
ну и уж в ханддере ты могешь делать что угодно от инициализации еще одного хипа до посылки юзера в сад 8)

Добавлено: 19 мар 2007, 16:24
sz
Эта мутная фигня с хендлерами и тп мне, безусловно, известна.
Тем кто ее придумал можно глаз и не выбивать, но щелбанов надавать стоило бы.

А те дураки, которые заставили простой new exception кидать, видимо были не в курсе, что и до них программы на плюсах писались. И писались из рассчета, что new возвращает 0 при нехватке памяти. Потому что в первых версиях Страуса это было документированное поведение.

Я, кстати, не помню, кто придумал швыряться - Страус или ансишные бойцы. Скорее всего ансишные. Страус, пока управлял стандартом, был гораздо осторожнее и разумнее.

Добавлено: 19 мар 2007, 16:28
sz
Есть, кстати, кроме предложенных, еще и третий вариант.
Посмотреть в мануалы компилятора и отключить нафиг ексепшены в new. Самый разумный, имхо.

Добавлено: 19 мар 2007, 16:59
aissp
Ты меня пугаешь. Ето было принято вроде году етак в 95, неужели в вашей конторе такой богатый на историю код? Времен етак Ф-19 и вольфа 3д? 8)

Добавлено: 19 мар 2007, 17:44
Azazello
aissp писал(а):На практике согласен видимо :) А так есть очень изяшное решение:

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

...
private:
void swap(qq& l, qq& r) throw();
};

qq& operator=(const qq& qRight) { 
    qq temp = qRight;
    swap(*this, temp); 
    return *this;
}; 
Я, конечно, не специалист, так что больно не бейте ;). По-моему, вариант со swap не самый эффективный из-за overhead плюс лишний вызов memcpy. А такой вариант не подойдёт (new выбрасывает exception)?

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

qq& operator =( const qq &qRight ) 
 {
  if( this != &qRight )
   {
    char *tmp = new char[ qRight.size_ ];
    memcpy( tmp, qRight.ptr_, size_ = qRight.size_ );
    delete[] ptr_;
    ptr_ = tmp;
   }
   
  return( *this );
 }

Добавлено: 19 мар 2007, 17:44
sz
aissp писал(а):Ты меня пугаешь. Ето было принято вроде году етак в 95, неужели в вашей конторе такой богатый на историю код? Времен етак Ф-19 и вольфа 3д? 8)
Эксепшены у нас отключены нафиг. Они же нам фрейм рейт убьют.

Ф-19 и вольф - не наши игры. Но код тех времен, почти наверняка, где-то в проектах еще сохранился.