В C ++, в отличие от других языков, вы должны явно думать о том, где вещи хранятся в памяти.Указатель говорит вам, где искать в памяти, чтобы найти что-то.По аналогии можно сказать, что вы смотрите на третье письмо в 5-м ряду на странице 124 книги.Если моя книга написана карандашом, я мог бы стереть слова на этой странице и заменить их другими словами, и хотя указатель остался бы прежним (то есть я смотрю на то же место в книге), на что указываетчтобы измениться.
Это то, что происходит в вашем коде.Каждый раз, когда вы читаете имя, вы стираете предыдущее имя и записываете новое имя в том же месте памяти.Таким образом, когда вы передаете указатель в своем конструкторе, вы рискуете памятью, которую вы указываете на изменение.
Чтобы исправить это, вам нужно сделать локальную копию имени.Это можно сделать с помощью строкового класса, как в ответе @Justin.Но для целей обучения (этот код немного сложнее), вот как вы можете выделить внутреннюю память (класс строки просто сделает это за вас):
class UserAccount {
public:
UserAccount(const char *name)
{
m_name = new char[strlen(name)+1];
strcpy(m_name, name);
}
~UserAccount()
{
delete [] m_name;
}
private:
char * m_name;
};
Обратите внимание, что мы сейчас используемдеструктор, потому что мы выделили память и должны снова ее освободить, когда класс будет удален.Также обратите внимание, что я не проверял, является ли переданное имя пустым, что должно быть сделано.И последнее замечание: строки неявно оканчиваются нулем, чтобы сообщить вам, когда вы достигли конца строки.Вот почему мы должны выделить большой размер - чтобы держать нулевое значение в конце строки.
Как указывал @Marc, вы также можете использовать strdup, но я подумал, что более длинное объяснение и показ явногораспределение памяти было бы полезно, чтобы лучше понять происходящее.