[완료] C++ 에서 const 관련 질문입니다..

anster의 이미지

안녕하세요~

C++ 공부중에 const 키워드와 관련된 궁금증이 생겨서 이렇게 질문드립니다.

제가 알기로 const 멤버 함수는

1. 내부에서 멤버 변수의 값을 조작할 수 없고
2. 클래스의 멤버 변수의 주소값을 리턴하거나
3. 상수화 되지 않은 함수, 즉 멤버 변수의 값을 조작하거나 멤버 변수의 주소값을 리턴하는 함수를

호출할 수 없다고 알고있는데

다음과 같은 경우에(편의상 생성자, 소멸자 등은 생략하겠습니다 ^^;)

class Person {
private:
char* name;
char phone[100];

public:
char* RetNamePtr(void) const {
return name;
}

char* RetPhonePtr(void) const {
return phone;
}
};

RetNamePtr에서는 컴파일 에러가 나지 않지만,
RetPhonePtr에서는 컴파일 에러가 나는데,

이러한 차이가 나는 이유가 변수 name의 경우 주소값을 알더라도 char* 형식이기때문에 내부 내용을 바꿀 수 없기 때문이며
이와는 다르게 변수 phone은 배열 형식이기때문에 주소값을 알게되면 내용을 바꿀 수 있기 때문인가요..?

잘 기억은 나지 않지만 metset..? metcpy 이런함수들은 해당 메모리에 바이트 단위로 내용을 써 넣을 수 있는것으로 아는데
그렇다면 char* 타입의 클래스 변수 주소를 리턴함으로써 변수 내용을 바꿀 수 있지 않나요 ^^;?

위와 같이 컴파일에서 에러 차이가 나는 이유가 궁금합니다..

* 추가질문

const 상수의 경우

이니셜라이져 기능을 이용해서

class AAA {
private:
const int id;

public:
AAA(int _id) : id(_id) {}
};

다음과 같이 초기화 할 수 있는것으로 아는데 그렇다면 클래스 내부 멤버에 char* name 과 같은 포인터형 변수가 있을때는
어떻게 생성자를 이용해서 초기화 할 수 있을까요..ㅠㅠ?

읽어주셔서 감사합니다.

neogeo의 이미지

char* RetPhonePtr(void) const  { .. }

에서의 const 는 멤버 변수나 리턴값의 constness 와는 전혀 관계 없이

"member 변수 내용을 바꾸지 못 하는" member method 의 선언식입니다. const 의 위치를 잘 보십시오.

즉 member 변수 전부를 const 취급하게 되므로 member 변수에 const 를 붙인것과 동일하게 됩니다. ( 그 함수의 scope 내에서는.. )

따라서

char* name;
char phone[100];

는 각각 char* RetPhonePtr(void) const 안에서

char* const name;
char const phone[100];

으로 취급됩니다.

따라서 함수 내부를 각각 풀어써 보면 결국 char* const 와 char const [] 를 char * 로 casting 해서 리턴하게 되는데, 이 경우 묵시적 캐스팅이 안되는 케이스는 후자이지요.

전자의 의미는 name 자체가 포인팅하는 위치만 바뀌지 않으면 상관없는 포인터 이므로 ( 그 포인팅 한곳의 값이 바뀌던 말던 ) 그 포인터를 char * 에 복사해도 아무 문제가 생길여지가 없습니다. 그러나 후자는 반드시 포인팅 하는 위치에 내용이 상수여야 하므로 const 가 없는 char* 에 복사하는것은 문제가 생길 여지가 있습니다. ( 물론 const casting 을 통해 날려버리고 강제로 복사는 가능합니다만, illegal behavior 를 부를 여지가 생기지요 ) 따라서 자연스럽게 금지 되는것입니다.

아래 코드를 실험해 보시면 좀 더 가볍게 이해가 가실 것 입니다.

    char a = 'a';
    char* const b = &a;
    char const c[1] = { 'c' };
 
    char* d;
 
    d = b;
    d = c;

Neogeo - Future is Now.

Neogeo - Future is Now.

anster의 이미지

감사합니다. ^^; 결국 char* const name은 char* 로 복사해도 가리키는 곳이 바뀌는것과 관련 없이 현재 가진 주소값이 바뀔 염려가 없으므로 리턴이 되고 char const phone[100] 의 경우에는 가리키는 곳의 내용이 상수여야 하므로 char* 을 통해 복사하면 조작의 염려가 있어서 리턴되지 않는다는거군요!! ㅠ_ㅠ 자세한 설명 감사드립니다.

===================

복군의 이글루
http://anster.egloos.com

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.