Встретил очередной нюанс с++:
Если класс не содержит явного копирующего конструктора или operator=, то они создаются неявно.
Об этом надо помнить.
Допустим у нас есть класс, который содержит в себе указатель на свой буффер.
Легко ошибиться и выполнить присваивание или вызвать копирующий конструктор для такого объекта.
Вот такой код запросто скомпилируется и будет работать неправильно.
Вывод программы будет такой:
Т.е. мы присвоили указатель data объекта a объектам b и c.
В результате у нас 3 раза освободился один и тот же указатель, а data объекта c вообще потерялся.
Решение — сделать private копирующий конструктор и operator=. При этом достаточно их просто объявить, тело функций добавлять не надо.
Описание взял отсюда, там же есть еще интересные факты:
http://www.rsdn.ru/forum/cpp/4896711.all
Если класс не содержит явного копирующего конструктора или operator=, то они создаются неявно.
Об этом надо помнить.
Допустим у нас есть класс, который содержит в себе указатель на свой буффер.
class buf_t { unsigned char* data; public: buf_t(size_t buf_size) { data=new unsigned char[buf_size]; printf("buf_t(): data=%p\n",data); } ~buf_t() { printf("~buf_t(): data=%p\n",data); delete[] data; } }; |
Легко ошибиться и выполнить присваивание или вызвать копирующий конструктор для такого объекта.
Вот такой код запросто скомпилируется и будет работать неправильно.
int main(int argc,char** argv) { buf_t a(1000); buf_t b(a); buf_t c(500); c=a; return 0; } |
Вывод программы будет такой:
buf_t(): data=00902DCC buf_t(): data=009031B8 ~buf_t(): data=00902DCC ~buf_t(): data=00902DCC ~buf_t(): data=00902DCC |
Т.е. мы присвоили указатель data объекта a объектам b и c.
В результате у нас 3 раза освободился один и тот же указатель, а data объекта c вообще потерялся.
Решение — сделать private копирующий конструктор и operator=. При этом достаточно их просто объявить, тело функций добавлять не надо.
class buf_t { unsigned char* data; public: buf_t(size_t buf_size) { data=new unsigned char[buf_size]; printf("buf_t(): data=%p\n",data); } ~buf_t() { printf("~buf_t(): data=%p\n",data); delete[] data; } private: buf_t(const buf_t&); void operator=(const buf_t&); }; |
Описание взял отсюда, там же есть еще интересные факты:
http://www.rsdn.ru/forum/cpp/4896711.all
Комментариев нет:
Отправить комментарий