2009-10-29 3 views
1

Мне нужно сохранить массив символов внутри класса, а затем вернуть его. Я должен признать, что я немного запутался в указателях и попробовал все, что мог, но не могу заставить его работать. Вот что у меня есть:Сохранение массива char в классе, а затем его возврат

#include <iostream> 
using namespace std; 

class Test { 
public: 
    void setName(char *name); 
    char getName(); 
private: 
    char m_name[30]; 
}; 

void Test::setName(char *name) { 
    strcpy(m_name, name); 
} 

char Test::getName() { 
    return *m_name; 
} 

void main() { 

    Test foobar; 
    char name[] = "Testing"; 
    foobar.setName(name); 
    cout << foobar.getName(); 
} 

Конечно, я ожидаю SetName(), чтобы сохранить строку «Проверка» внутри класса, и GetName() должен возвращать «Тестирование». Но вместо этого я получаю только первую букву Т. Что я делаю неправильно?

Я предполагаю, что я должен использовать std-строки, но сначала я хотел бы понять, почему это не работает. Насколько я знаю, это должно работать и с массивами символов?

+0

Вы обращаете внимание на предупреждения компилятора? :( – 2009-10-29 07:28:22

ответ

6

Просто возвращает указатель:

const char* Test::getName() const 
{ 
    return m_name; 
} 

и добавить конструктор для class Test что бы нуль-прекратить инкапсулированный массив:

Test::Test() 
{ 
    m_name[0] = 0; 
} 

так, что вы не просите неприятности, если кто-то создает экземпляр class Test и не вызывает setName() экземпляра.

+3

Я бы также предложил использовать strncpy() вместо strcpy(), а так как это C++, вы должны использовать std :: string вместо указателей на char, которые являются задержкой с C – Wernsey

+3

+1 относительно использования 'std :: string'. Если вы по какой-то причине должны использовать C-строку, вы можете вернуть C-строку, используя' '' функцию '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' –

1

В Test::getName() вы просто возвращаете один символ (первый символ). Вместо этого вы должны вернуть адрес первого символа, откуда строка начинается то изменить тип возвращаемого к char* и оператор возврата к return m_name;

0

И безопаснее использовать strncpy() чем strcpy() в void Test::setName()

1

Если у вас есть указатель, p, оператор разыменования указателя * «следует» указателю, поэтому выражение *p оценивает любой объект, на который указывает указатель.

Во многих ситуациях имя массива, такого как m_name, может вести себя как указатель. Таким образом, *m_name оценивает первый char в массиве, так как это тип имени массива, когда он интерпретируется как указатель, указывает на.

Поскольку строки в C представлены в виде указателей на символы, вы не должны разыменовывать указатель, а возвращать его нетронутым.

Многие предложили вам использовать strncpy() для ввода входной строки в ваш массив, так как она выполняет (сортировку) проверку границ. Тем не менее, это не оптимально, семантика нечетна и копирование строки в ограниченный буфер действительно не то, для чего она была предназначена. Лучше исследовать, если у вас есть многообразие snprintf() функции в вашей среде, и использовать это как так:

snprintf(m_name, sizeof m_name, "%s", name); 
0

Если вы хотите, чтобы это C++ просто не использовать полукокс указатели, если у вас есть очень, очень конкретная причина для этого!

Перехода от указателя к полукоксу STD :: строки и посмотреть, если это решит вашу проблему:

#include <iostream> 
#include <string> 
using namespace std; 

class Test { 
public: 
    void setName(std::string name); 
    std::string getName(); 
private: 
    std::string m_name; 
}; 

void Test::setName(std::string name) { 
    m_name = name; 
} 

std::string Test::getName() { 
    return m_name; 
} 

void main() { 
    Test foobar; 
    foobar.setName("Testing"); 
    cout << foobar.getName(); 
} 

Для бонусных очков, сделать тип параметра в SetName константной зЬй :: строки &.

Смежные вопросы