Страница 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

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();
}
}
}
типа такого
ну и уж в ханддере ты могешь делать что угодно от инициализации еще одного хипа до посылки юзера в сад

Добавлено: 19 мар 2007, 16:24
sz
Эта мутная фигня с хендлерами и тп мне, безусловно, известна.
Тем кто ее придумал можно глаз и не выбивать, но щелбанов надавать стоило бы.
А те дураки, которые заставили простой new exception кидать, видимо были не в курсе, что и до них программы на плюсах писались. И писались из рассчета, что new возвращает 0 при нехватке памяти. Потому что в первых версиях Страуса это было документированное поведение.
Я, кстати, не помню, кто придумал швыряться - Страус или ансишные бойцы. Скорее всего ансишные. Страус, пока управлял стандартом, был гораздо осторожнее и разумнее.
Добавлено: 19 мар 2007, 16:28
sz
Есть, кстати, кроме предложенных, еще и третий вариант.
Посмотреть в мануалы компилятора и отключить нафиг ексепшены в new. Самый разумный, имхо.
Добавлено: 19 мар 2007, 16:59
aissp
Ты меня пугаешь. Ето было принято вроде году етак в 95, неужели в вашей конторе такой богатый на историю код? Времен етак Ф-19 и вольфа 3д?

Добавлено: 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д?

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