[완료] C++ 클래스에서 const char형 포인터를 초기화 해주고 싶습니다
글쓴이: sinsy200 / 작성시간: 목, 2008/04/10 - 12:05오후
한참 C++를 배우고 있는 학생입니다. const는 변경되지 않는 값에 붙여 준다고 배웠거든요. 실수로 변경하려해도 컴파일 오류가 나와서 막아준다고 배웠습니다.
오늘 클래스의 const멤버 함수를 초기화 해주는 방법에 대해 배웠습니다.
class people
{
const int ssn;
char *name;
int age;
public:
people(char *_name, int _ssn, int _age): ssn(_ssn)
{
name = new char[strlen(_name) + 1];
strcpy(name, _name);
age = _age;
}
~people()
{
delete[] name;
}
}
대충 이런 클래스가 있다고 했을 때요. 개인에게 주어지는 ssn은 변경되지 않기 때문에 const라는 키워드를 붙여주어서 만들었다고 생각하면요.
저는 이름도 변경되지 않기 때문에 const를 붙여주고 싶어요. 근데, 그럴 경우 초기화는 어떻게 하나요?
const char *name;
이렇게 멤버 변수를 선언하면 생성자에 strcpy에서 에러가 나요. const라서 변경할 수 없어서 나오는 거 같은데.
Initializer 에서 제공하는 방법이 있나요?
아니면 저런 것은 아예 애초부터 불가능한 것인가요?
Forums:
char* 대신 std::string을
char* 대신 std::string을 사용하는 것은 어떤가요?
people(char *_name, int
people(char *_name, int _ssn, int _age): ssn(_ssn), name(_name)
으로 하시면 될것 같은데요.
---
그리고 앞의분 말씀처럼 std::string 등을 쓰시는것을 권해드립니다..
더불어 naming convention도 같이 공부하시는것도요..
naming convention이란 건
naming convention이란 건 검색해보니 이름 지을 때 뭔가 정해진 규칙 같은 거네요.
참고할게요 ^^
auditory 님처럼
auditory 님처럼 소위'콤마 초기화'라는 걸 이용하면 됩니다. 다만 이경우 댕글링 포인터가 될 수 있으므로 역시 char *보다는 string을 쓰시는걸 추천합니다.
string을 쓰지 않는 특별한 이유가 있으신가요?
사실은 오늘 C++ 수업
사실은 오늘 C++ 수업 시간에 클래스에 const변수를 선언하고 저런식으로 초기화하면 된다는 것을 배웠습니다.
그런데, 저는 name도 바뀌지 않는 값이니 const로 해줘야하지 않을까 생각을 했고요.
단순하게 : name(_name) 이라고 한다면 객체가 자신만의 소중한(*^^*) name 속성을 가지는 것이 아니지 않나요?
char temp[80];
cin >> temp;
people p1(temp, ~, ~);
이런식으로 한다면 temp가 바뀌면 p1의 이름도 바뀌는 것 아닌가요?
지금 생성자에서처럼 객체 자신만의 name 속성에 이름을 복사해주고 다음부터 변경이 안 되도록 하는 방법이 없을까?
하는 것이 저의 궁금증이었어요.
교수님에게 물었는데 잘 모르시던데요. 그걸 역으로 숙제로 내주셨습니다. -_-;;
할 수 있는 방법이 있는지 없다면 왜 안 되는지 조사해 오라는 것이었습니다.
그런데, 댕글링 포인터란 것은 무엇인가요?
댕글링 포인터에
댕글링 포인터에 대해서는 구글에서 찾아보면 될듯하구요, 아직 배우지 않았거나 문제 조건때문에 std::string을 쓸수 없다면, const_cast나 C스타일의 캐스팅연산자를 이용해서 const를 임시로 때서 strcpy로 넘기는 방법뿐일 듯하네요.
감사합니다.
감사합니다. const_cast를 이용하여 해결하면 되겠네요.
한가지만 더요. const_cast에 대해 찾아보다가 winapi 사이트의 설명을 보았는데요.
http://www.winapi.co.kr/clec/cpp3/33-2-4.htm
이런 글귀를 보았는데요. 혹시 설명해 주실 수 있을까요?
일단 어떤
일단 어떤 캐스팅이던 신중하게 써야합니다.
이경우에, 한번 거꾸로 생각해보세요.
c1에 str을 대입했고, 또 c2에 c1을 대입했기 때문에 결국 str과 c1은 같은 곳을 가리킵니다.
즉, 마지막의 c2[0]='a'는 str[0]='a'와 동등하다고 생각할 수 있습니다.
그러므로 결국 주어진 코드는
char str[] = "string";
str[0]='a';
라고 하는 경우와 같은 결과를 초래합니다.
이때, char str[]="string"대신에 char *str = "string"이라고 하면 str[0]='a'같은 대입은 불가능합니다.
왜냐면 전자는 "string"을 넣을 만큼의 메모리를 확보한후에, 그 메모리의 값들을 "string"으로 초기화하는 것이므로, str[0], str[1]..등도 모두 각각이 (값을 바꿀 수 있는) 변수인데에 반해, char *str = "string"의 경우는 (값을 변경할 수 없는) 상수 문자열 "string"을 가리키는 포인터 str을 선언하는 구문이기 때문에, 이것의 값을 변경한다는 것은 불가능합니다.
예를 들자면, str[0]은 's'이므로, 변수가 아닌 's'에 'a'를 대입하는 셈이되는 것입니다.
c1의 경우는 const이므로 이러한 대입은 컴파일시에 에러가 발생하여 불가능하지만, c2로 대입하면서 상수성을 때버리면, 컴파일시에는 아무 문제가 없는 듯이 컴파일이 되지만, 결국 런타임시에 프로그램이 죽어버리는 사태가 될수도 있습니다.
그리고,
이건 이전에 질문하신건데 지나쳤네요. 여기서 처음에 구현하신대로 new로 메모리 할당한후 strcpy로 복사할 경우, temp가 바뀌어도 p1의 name은 바뀌지 않습니다.
왜냐면 p1.name은 temp를 대입한게 아니라 새로운 메모리를 할당해서 그 내용을 복사한 경우(deep-copy)이기 때문입니다.
아..친절한 설명
아..친절한 설명 감사합니다.
그리고 마지막 건은
이렇게 했을 때 그렇지 않냐는 뜻이었습니다.
다시 한번 새로운 걸 배우게 되네요. char[] 와 char*의 차이에 대해서.. 감사합니다 ^^;
> people(char *_name, int
> people(char *_name, int _ssn, int _age): ssn(_ssn), name(_name)
> 으로 하시면 될것 같은데요.
라는 답글은 사실 문제를 최대한 단순화시켜서 드린 답변이었습니다.
말씀하신대로 const가 아닌 char* 변수를 넘겨줄 때는
굉장히 위험한 방법입니다.
(넘어간 포인터가 어느시점에 없어진다면 dangling pointer문제가 쉽게 생기겠죠.)
말씀드린 경우도 _name도 const char* 인 경우에 한해서 사용됩니다.
말씀하신것처럼 런타임에서 사용자에게서 입력받은 데이터라면 const라고 보기가 어렵습니다.
const 변수는 선언시점에 초기화되는 변수입니다.
조금 다른 얘기지만
나이 (age) 같은건 무조건 양수 일테니
unsigned를 쓰는것도 좋겠네요.ㅋ
땀나는 맛이 있기에 세상은 살맛나는 것이지
땀나는 맛이 있기에 세상은 살맛나는 것이지
댓글 달기