Rick York
Это выглядит как плохой дизайн для меня. Метод SetPersonInfo просто назначает переменные, что нормально. Проблема в том, что деструктор всегда удаляет массив. Если бы имя было литеральной строкой или другими не выделенными данными, то это вызвало бы исключение. По-видимому, это предполагает, что переданное имя также было выделено. Я думаю, что конструктор, принимающий аргументы, должен быть реализован как метод SetPersonInfo, чтобы он всегда делал копию, и это означало бы, что деструктор всегда безопасен. Вот что я считаю лучшей реализацией.
class Person
{
char * name;
int age;
public:
Person()
{
name = NULL:
age = 0;
}
Person(const char * myname, int myage)
{
SetInfo( myname, myage );
}
void SetInfo(const char * myname, int myage)
{
name = strdup( myname );
age = myage;
}
void ShowInfo() const
{
cout << name << ' ' << age << endl;
}
~Person()
{
free( name );
}
};
Да, я знаю, что он использует текстовые строки в стиле C, но оригинал тоже использовал свой вызов strcpy. Лучшим способом было бы использовать строку std::, и тогда не было бы необходимости в выделении или освобождении. Класс std::string управляет всем этим сам. Вот что такое реализация :
class Person
{
std::string name;
int age;
public:
Person()
{
age = 0;
}
Person(const char * myname, int myage)
{
SetInfo( myname, myage );
}
void SetInfo(const char * myname, int myage)
{
name = myname;
age = myage;
}
void ShowInfo() const
{
cout << name << ' ' << age << endl;
}
~Person()
{
}
};
Как видите, все немного проще.
서형박
Большое вам спасибо за Ваш полезный ответ!. Еще один вопрос заключается в том, что вместо использования strdup параметр myname должен передавать адрес переданной строки в name как есть? например, 'name = myname'
Rick York
Во втором примере name-это строка std:, и ее оператор присваивания принимает аргумент const char * и делает его копию. Strdup делает по существу то же самое в первом примере, за исключением того, что это простая версия C.