ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 함수 반환값 const / 멤버함수 const
    쥬신게임아카데미/C++ 2016. 1. 6. 15:35

    주제 : 멤버함수의 반환값은 Const로 하여라.

    안녕하세요~ : ) Crc12입니다.

    이번주제는 멤버함수의 반환값을 Const로 하는 이유에 대해서 설명을 하려고 합니다.
    아래에나오는 함수는 문자열을 이용하는 함수인데요 그 함수의 반환값에 대해서 설명하려고합니다.

    우선 아래의 코드에 주목해 주세요. ( 적당한 소스가 될지는 모르겠습니다... )
    우선 아래에서 CMky라는 클래스를 선언하였습니다.

    class CMky
    {
    // Member Variable
    private:
            char *m_szString;
           
    // Operator
    public:
            const char *GetString();

    // Member Function
    public:
            CMky()        {        m_szString = NULL ,
                                    m_szString = new char[255] ,
                                    strcpy ( m_szString , "abcdefghijklmnopqrstuvwxtz" );
                            };       

            ~CMky() {        delete [] m_szString ,
                                    m_szString = NULL;
                            };
    };

    const char *CMky::GetString()
    {
            return m_szString;       
    }

    int main(int argc, char* argv[])
    {
            char *mkydata = new char[255];       
            CMky *mkyclass = new CMky();
           
            //mkydata = mkyclass->GetString(); <== 이렇게 하면 안되니까 밑에 처럼 복사했다 ㅡㅡㆀ
            //즉 mkydata는 mkyclass의 변수를 엑세스 할수는 없다. 다만 복사한 값을 가질수만 있다.
            //mkyclass의 멤버변수를 엑세스 할수 있게 한다면 멤버변수를 공용으로 만들어라.
            //위는 private로 선언되어 있는데 포인터를 넘겨줄경우 다른곳에서 변수를 엑세스할수 있고
            //이는 C++규정에 위배된다.

            strcpy ( mkydata , mkyclass->GetString() );
            printf ( "%sn" , mkydata );
           
            delete [] mkydata;        // 2에서 배웠던 new와 delete의 형식 맞추기.
            delete mkyclass;
            return 0;
    }


    중요한것은 CMky클래스의 멤버함수인 GetString함수가 Const를 이용했다는것입니다.

    여기서 중요한것...

    A 멤버의 Astring라는 데이터가 있다고 가정합니다.
    Astring의 주소는 100이라고 기억하세요.

    여기서 GetString을 단순히 char *GetString을 하면 현재 Astring변수의 주소 100을 리턴하죠?
    만일 메인에 Bstring라는 변수가 있고 다음과 같이 실행을 했습니다.

    Bstring = A->GetString();
    이렇게 되면 Bstring는 뭘 가리키고 있죠? Astring의 주소를 알고 있죠...

    만일 A클래스의 Astring멤버변수가 private로 선언되어 있는데...

    strcpy ( Bstring , "aaaa" ); <= ㅡㅡㆀ

    라고 했다면 Astring값은??? aaaa로 바뀌겠죠... 이유는... GetString가 주소.. 즉...
    private로 선언된값에 모든 권한을 준것이나 마찬가지이죠 마치 해킹을 당한것처럼요...

    클래스 내부를 건드리게 하려면 멤버변수를 공용으로 만들어야 합니다.
    private로 선언된것을 외부에서 건드리면 안되요~! 그래서 Const로 멤버함수를 만들고
    만일 값을 얻고 싶다면 복사본을 쓰라는거죠 : )

    위의 소스는 자료실에 등록해놓을께요 : )

     


    제목: 하지만..

    글쓴이: gryu , 글쓴때: 5/16/01 1:16:38 am


    원한다면 강제 형변환으로 밀어버릴 수 있습니다^^

    예를 들어서
    ...
    char* mkydata;

    mkydata = (char*)mkyclass->GetString();
    strcpy ( mkydata, "Hello");
    printf ( "%sn" , mkyclass->GetString());
    ...
    // delete [] mkydata
    ...

    이러면 m_szString에도 "Hello"가 들어갑니다... 즉 const 만으로는 충분한 보호 장치가 되지 못합니다.

     

     

     


    class CObj
    {
    public:
     const int m_iValue;
     int m_iData;

    public:
     //----------------------시작---------------------//
     int* GetValue() const //const가 뒤에 붙으면
     {//여기부터
      //아래의 에러이유는 외부에서 포인터를 통해서 값을 변경할 ***가능성***이 있기 떄문에 에러발생
      //return &m_iData; //값변경 가능성이 있으니까..에러!..일반변수 말고 포인터의 경우에는???? 포인터의 값은 주소니까...주소변경이 되면 에러! *ptr 이건 에러안남 아래
      //return *m_iData; 또는 멤버변수가 int* m_iData라면 return m_iData; 에러 안남!
     }//여기까지 안의 변수들 전부 상수화!!

     //const int* GetValue() //const가 반환값에 붙으면 ****받는 반환값***도 const가 붙어야 한다.
     //{//여기부터
     // return &m_iData;
     //}//여기까지 별다른 증상없음
     //----------------------끝---------------------//

     //----------------------시작---------------------//
     void ShowConst() const //1번
     {
      cout << "const" << endl;
     }

     void SHowConst() //2번
     {
      cout << "const" << endl;
     }

     //만약에 객체에 const가 안붙은경우 1,2번 둘다 가능하지만 오버로딩시에는 2번이 호출되고...만약에 2번이 없으면 1번이 호출된다.
     //하지만 const이 붙은 객체에는 1번만 호출된다. 2번은 죽어도 안됨

     //----------------------끝---------------------//

Designed by Tistory.