ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20141008 (C++ 맴버 이니셜라이저)
    부산IT학원/스마트컨트롤러 2014. 10. 8. 11:50

    154일차








    ----------

    C++

    ----------





    ------- 맴버 이니셜라이저(Member Initializer)

    우선 예제를 보자.


    class Point

    {

    private:

    int x;

    int y;


    public:

    Point()

    {

    cout << "Point 디폴트 생성자 호출" << endl;

    x = 0;

    y = 0;

    }


    Point(int x, int y)

    {

    cout << "Point 생성자 호출" << endl;

    Point::x = x;

    Point::y = y;

    }


    ~Point()

    {

    cout << "Point 소멸자 호출" << endl;

    }


    void Print()

    {

    cout << "[" << x << ", " << y << "]\n";

    }

    };


    class Rectangle

    {

    public:

    Point upLeft;

    Point lowRight;


    public:

    Rectangle()

    {

    cout << "Rectangle 디폴트 생성자 호출" << endl;

    }


    Rectangle(int x1, int y1, int x2, int y2)

    :upLeft(x1, y1), lowRight(x2, y2) // 함수의 코드를 실행전 이 코드를 먼저 수행

    {

    cout << "Rectangle 생성자 호출" << endl;

    }


    ~Rectangle()

    {

    cout << "Rectangle 소멸자 호출" << endl;

    }


    void Print()

    {

    upLeft.Print();

    lowRight.Print();

    }

    };


    int main(void)

    {

    Rectangle obj1;

    obj1.Print();


    Rectangle obj2(1,2,3,4); // 요놈을 자세히 볼 것.

    obj2.Print();


    return 0;

    }


    결과



    이렇듯 Rectangle 객체가 생성되기 전에 Point 객체가 먼저 생성되는데


    Rectangle(int x1, int y1, int x2, int y2)

    :upLeft(x1, y1), lowRight(x2, y2) // 함수의 코드를 실행전 이 코드를 먼저 수행

    {

    cout << "Rectangle 생성자 호출" << endl;

    }


    생성자와 중괄호 사이에 저렇게 넣으면 Point 객체가 생성되기 전에 빨강줄 코드부터 수행한다.

    이것이 맴버 이니셜라이저이다.




    또 이런 경우도 가능하다.

    class Rectangle

    {

    public:

    Point upLeft;

    Point lowRight;

    const int iNum; // const int iNum = 100;  //error


    public:

    Rectangle()

    :iNum(100)

    {

    cout << "Rectangle 디폴트 생성자 호출" << endl;

    // iNum = 100; // error;

    }

    };





    --- C++에서는 변수 초기화에 괄호를 사용하여서도 가능하다.


    예)

    int iNum2(200);    // int iNum2 = 200;

    cout << "iNum2 : " << iNum2 << endl;


    int * ip(&iNum2);    // int * ip = &iNum2;

    cout << "*ip : " << *ip << endl;


    char buf[]("hihihi");    // char buf[] = "hihihi";

    cout << "buf : " << buf << endl;


    char * pbuf("this is test");    // char * pbuf = "this is rest";

    cout << "*pbuf : " << pbuf << endl;


    결과










    --- 생성자, 소멸자 다른 예제


    class Point

    {

    private:

    int x;

    int y;


    public:

    Point()

    {

    cout << "Point 디폴트 생성자 호출" << endl;

    x = 0;

    y = 0;

    }

    ~Point()

    {

    cout << "Point 소멸자 호출" << endl;

    }

    };


    void test(Point obj)

    {

    80: Point obj1;


    82: obj1 = obj;

    }


    int main()

    {

    87: Point objA;


    89: test(objA);


    91: return 0;

    }


    결과



    생성자가 두 번 호출되었고, 소멸자는 3번 호출되었다.

    어셈블리로 확인해 본 결과.


    _main PROC ; main 함수

    ; Line 87

    lea ecx, DWORD PTR _objA$[ebp]

    call ??0Point@@QAE@XZ         ; Point::Point 생성자 호출

    mov DWORD PTR __$EHRec$[ebp+8], 0

    ; Line 89

    mov eax, DWORD PTR _objA$[ebp+4]

    push eax

    mov ecx, DWORD PTR _objA$[ebp]

    push ecx

    call ?test@@YAXVPoint@@@Z ; test

    add esp, 8

    ; Line 91

    mov DWORD PTR $T30281[ebp], 0

    mov DWORD PTR __$EHRec$[ebp+8], -1

    lea ecx, DWORD PTR _objA$[ebp]

    call ??1Point@@QAE@XZ         ; Point::~Point 소멸자 호출

    mov eax, DWORD PTR $T30281[ebp]


    ?test@@YAXVPoint@@@Z PROC ; test 함수

    ; Line 80

    lea ecx, DWORD PTR _obj1$[ebp]

    call ??0Point@@QAE@XZ         ; Point::Point 생성자 호출

    ; Line 82

    mov eax, DWORD PTR _obj$[ebp]

    mov DWORD PTR _obj1$[ebp], eax

    mov ecx, DWORD PTR _obj$[ebp+4]

    mov DWORD PTR _obj1$[ebp+4], ecx

    ; Line 83

    lea ecx, DWORD PTR _obj1$[ebp]

    call ??1Point@@QAE@XZ         ; Point::~Point 소멸자 호출

    mov DWORD PTR __$EHRec$[ebp+8], -1

    lea ecx, DWORD PTR _obj$[ebp]

    call ??1Point@@QAE@XZ         ; Point::~Point 소멸자 호출


    어셈에서 이런 식으로 처리했다.


    생성자가 main에서 Point objA를 선언하면서 한 번,

    test에서 Point obj1을 선언하면서 한 번 호출하고,


    소멸자는 main return 하면서 한 번,

    test에서 return하면서 obj1, obj가 소멸되면서 두 번 호출하였다.








Designed by Tistory.