ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 생성자함수에서 생성자(오버로딩)함수를 호출할때 주의할 점
    Programming/C,C++,C# 2008. 1. 11. 21:53

    2012/03/26 해당글은 모든 컴파일러에서 사용할 수 있는 방법은 아닙니다. 
    자세한 내용은 
    http://www.gpgstudy.com/forum/viewtopic.php?p=24230 을 참고해주시기 바랍니다.
     

    class CTest
    {
    public:
          int m_val;

          CTest()
          {  
             CTest(0);
          }

          CTest(int val)
          {
                m_val = val;
          }

          ~CTest(){}
    };

    int main()
    {
     CTest test;
     printf("m_val : %d\n", test.m_val);
     return 0;
    }

    CTest클래스가 있습니다.
    특별한 기능은 없고  생성자함수에서 멤버변수 m_val를 초기화를 하고있습니다.

    클래스선언시에 인자값을 주지않으면 0으로 초기화 되도록 되어있습니다.
    위 예제에서는 인자값을 주지않을경우 CTest() 생성자에서 CTest(int val)생성자 함수를 호출하는 방법을 사용하여
    멤버변수를 초기화를 합니다.

    예제에서 test로 선언된 CTest클래스의 멤버변수 m_val의 값을 출력하면 어떤값이 나올까요?

    제가 생각한대로는 당연히 0이 나올것이라고 생각을 했었습니다.

    근데 결과는

    m_val : -858993460

    0으로 대입시켰는데 제대로 안되었습니다.



    왜 그럴까? 해서 찍어봤습니다.

    class CTest
    {
    public:
          int m_val;

          CTest()
          {  
               puts("CTest() Call");
               CTest(0);
          }

          CTest(int val)
          {
                m_val = val;
                printf("CTest(int val) m_val=%d\n", m_val);
          }

          ~CTest()
          {
                puts("~CTest() Call");
          }
    };

    int main()
    {
     CTest test;
     printf("m_val : %d\n", test.m_val);
     return 0;
    }

    결과는

    CTest() Call
    CTest(int val) m_val=0
    ~CTest() Call
    m_val : -858993460
    ~CTest() Call

    예상외의 결과가 나왔습니다.
    소멸자가 2번호출이 되었네요.. 결과적으로 2개의 클래스객체가 생성이 되었다는 말인듯합니다.

    결국 CTest()생성자함수에서 호출한 CTest(int val)생성자함수가 자신의 함수를 호출한게 아니라
    새로운 객체를 생성시켜 새로생성된 객체의 멤버변수를 0으로 세팅하고..

    원래 0으로 세팅하려던 m_val은 초기화가 안된 상태 그대로 쓰레기값이 나왔던 것입니다.

    음.. 생성자함수만이 가진 특성인지는 잘모르겠지만..

    굉장히 주의를 해야할 부분이란것을 느꼈습니다. 왜냐하면 에러아니 에러이기때문에..




    아무튼 위와 같이 생성자에서 생성자(오버로딩)를 정상적으로 호출하려면 어떻게 해야할까?

    class CTest
    {
    public:
          int m_val;

          CTest()
          {  
               puts("CTest() Call");
              this->CTest::CTest(0);   // this포인터를 사용
          }

          CTest(int val)
          {
                m_val = val;
                printf("CTest(int val) m_val=%d\n", m_val);
          }

          ~CTest()
          {
                puts("~CTest() Call");
          }
    };

    int main()
    {
     CTest test;
     printf("m_val : %d\n", test.m_val);
     return 0;
    }




    CTest() Call
    CTest(int val) m_val=0
    ~CTest() Call
    m_val : 0
    ~CTest() Call

    this포인터로 확실하게 자기자신을 가리켜야하는군요...

    사실 이렇게 쓰는 경우는 정말 흔하지는 않을것 같습니다만..

    웬만하면 생성자에서는 생성자를 호출하지 않는 방법으로 코딩을 하는것이 가장 좋은 방법인것 같습니다...

Designed by Tistory.