Brise

[C++ 기본 2] 9. 초기화리스트 본문

프로그램/C,C++

[C++ 기본 2] 9. 초기화리스트

naudhizb 2022. 3. 2. 23:47
반응형

C언어를 해본 사람은 알겠지만, 초기화와 대입은 얼핏 보면 비슷하지만, 실제로는 매우 다르다.

예를 들어

const int ca = 3;
const int cb;
cb = 2;

와 같이 초기화로만 값 지정이 가능하고 대입으로는 값 지정이 불가능한 경우도 있다.

// 9_초기화리스트1    85page ~
#include <iostream>

class Point
{
    int x, y;
public:
    //Point(int a = 0) : x(a) {}

    Point(int a  = 0, int b = 0) 
        : x(a), y(b) // 초기화리스트.  대입이 아니라 초기화
    {
        x = a; // 대입
        y = b; 
    }
};
int main()
{
    Point pt(0, 0);

    int a = 0;  // 초기화. 만들면서 넣기
                // a가 class type이면 생성자 호출로 초기화
        
    int b;    // b가 class type이면 생성자 호출
    b = 0;    // 대입. 만들어진 메모리에 넣기.
            // b.operator=(0) 이라는 대입연산자 함수 호출
}

C++에서는 클래스 초기화 시 생성자에서 특수한 문법을 통하여 클래스 변수에 대한 값을 초기화 할 수 있도록 지원하고 있다.


// 클래스안에 const 멤버, 참조 멤버 등이 있다면 
// 반드시 초기화 리스트를 사용해야 한다. - 87 page

class Test
{
    int& r;
    int n = 0;    // C++98까지는 error. C++11 부터가능
    const int c = 10;
public:
    Test() {}
    Test(int a, int b) : n(a), c(b) // ok...
    {
        //n = a;
        //c = b; // ??error. 대입하는 코드 입니다.
    }
};
int main()
{
    Test t(1, 10);
    //const int c; // C 언어 : 경고, C++ : 에러.
}

물론 C언어와 비슷하게 상수에 대해서는 초기화 문법 사용이 강제된다.

만약 클래스의 멤버로 클래스가 있고 기본 생성자를 가지고 있다면 어떻게 될까?

// 9_초기화리스트1    85page ~
#include <iostream>

class Point
{
    int x, y;
public:
    Point(int a, int b): x(a), y(b) 
    {
    }
};

// 클래스의 멤버로 "디폴트 생성자(인자없는 생성자)"가 없는 타입이
// 있다면
// C++98 스타일 : 반드시 초기화 리스트에서 초기화 해야 한다.
// C++11 : 멤버 변수 선언시 {} 사용가능. Point ptFrom{0,0}
//           

class Rect
{
    int data = 0;
    Point ptFrom;
    Point ptTo;
public:
    Rect() : ptFrom(0,0), ptTo(0,0)
    {
        //ptFrom(0, 0); // ? ptFrom 이라는 함수를 호출하는 코드        
                        // error
    }
};
int main()
{
    Rect r; // 잘 생각해 보세요. 함수가 총 몇번 호출?
}

정답은,, 표준 따라 다르게 할 수 있다이다. C++98 표준에서는 초기화 리스트에서 초기화를 수행하여야만 하지만, C+++11 표준에서는 멤버 선언 시 기본값을 적용 가능하다.

// 9_초기화리스트1    85page ~
#include <iostream>
// 주의 사항 : 초기화 리스트에 놓인 순서가 아니라..
//      멤버 데이타가 놓은 순서 대로 초기화 된다. - 88 page
class Point
{
public:
    int x, y;

    Point() : y(0), x(y)
    {
    }
};
int main()
{
    Point pt;
    std::cout << pt.x << std::endl; // ?
    std::cout << pt.y << std::endl; // ?
}

초기화 리스트의 재미있는 점 중 하나는 초기화 리스트의 동작 순서가 리스트에 적은 순이 아닌 멤버의 나열 순서라는 점이다. 즉, 초기화 리스트는 선순위를 가지지 않고 컴파일러에 의하여 재배열 될 수 있다는 이야기이다.

반응형

'프로그램 > C,C++' 카테고리의 다른 글

[C++ 기본 2] 12. 객체 복사(shallow copy)  (0) 2022.03.03
[C++ 기본 2] 11. 복사 생성자  (0) 2022.03.03
[C++ 기본 2] 10. explicit  (0) 2022.03.02
[C++ 기본 2] 8. 생성자  (0) 2022.03.02
[C++ 기본 2] 7. 접근지정자  (0) 2022.03.02
[C++ 기본 2] 6. STL  (0) 2022.03.02
[C++ 기본2] 5. OOP(Stack example)  (0) 2022.02.24
Comments