Проблема с созданием класса
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.
Всем привет. Решаю задания на cppstudio.com. Дошёл да задания: http://cppstudio.com/post/8318/
Пишу код:
Файл main.cpp:
Ну и файл func&class.h, соответственно:
Как видно, в главном файле пока только тест на вывод ин-фы, и он не прошёл.
Выдаёт ошибки:
'std::ios_base::ios_base(const std::ios_base&)' is private
, а ругается он на строчку в файлеios_base.h
, где объявлено:а так же
initializing argument 1 of 'std::ostream& operator<<(std::ostream, zooshop&)'
на строчку:Мне лично вообще ничего не понятно.Может вам что-то известно по данному поводу?
P.S.:Как вы, наверное, заметили, в функции
name
иkind_animal
есть такая конструкция:
она предназначена для того, чтобы случано в вызывающей среде, где получили указатель на строку с именем, не поменяли это самое имя. Имя копируется в отдельную строку, а затем эта строка(точнее указатель на неё) возвращается. Но компилятору мои амбиции не по душе. Он выдаёт предупреждение:
address of local variable 'ret' returned
В чём дело?
Первое:
Второе. Компилятор правильно ругается: после выхода из функции, память, отведённая в стеке под массив
ret
будет освобождена и, скорее всего, её содержимое будет изменено при следующем вызове любой функции или при объявлении локальной переменной.Выхода из этой ситуации, как минимум, три:
(1) Объявить/определить метод так:
Что однако не спасает от изменения содержимого строки при помощи явного приведения типа к
char *
.(2) Создавать копию строки в куче и возвращать на неё указатель. Это совсем плохо, поскольку память надо будет освобождать (а) явно и (б) совсем в другом месте.
(3) Копировать строку из класса в буфер, предоставляемый вызывающим кодом. Это наиболее приемлемый вариант.
Кстати, непонятно почему ты так переживаешь за содержимое поля
_kind_animal
. Ты сам предоставляешь открытый методvoid kind_animal( const char *new_kind )
для изменения этого поля.Третье. Всякая мелочь.
(1) Зачем писать код для функций
когда в
<string.h>
имеются их аналоги? Кроме того, вместо функцииstrcpy()
рекомендуется использовать функциюstrncpy()
с контролем длины строки.(2) Функция сравнения строк написана неаккуратно. Если вторая строка короче первой, то возможен выход за границу массива.
(3) Аналогично с функцией
_strcpy()
: отсутствует контроль выхода за границу массива.(4) Дублирование кода в:
лучше использовать вызов метода
set_all()
в конструкторах. Тогда, при необходимости изменений, править придётся только в одном месте.(5) Для данного класса деструктор пока не нужен.
(6) Заголовочный файл (.h) должен содержать только объявления. Реализация должна быть в файле .cpp.
(7) При такой перегрузке оператора
,
нарушается семантика. Так делать не рекомендуется.(8) Перегрузку операторов типа
лучше реализовывать так:
При такой сигнатуре при вызове метода не будет выполняться создание временного объекта типа
zooshop
для параметра.(9) Всё?..
Спасибо, Череп!