본문 바로가기
  • 쓸쓸한 개발자의 공부방
C++

[C++] Class : 멤버 초기화 리스트 (member initializer lists)

by 심찬 2021. 8. 19.

 

 

멤버 초기화 리스트 (member initializer lists)

 

생성자 괄호 ( ) 뒤에 콜론 (:) 을 표기하고 멤버를 초기화 하는 것

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

 

대입 방식이 아닌 초기화 방식이다.

멤버 초기화 리스트를 사용하는 방향이 성능면에서 더 좋다.

 

클래스 선언부 구현부가 분리되어 있을 때, 초기화 리스트는 구현부에 작성한다.

 

#include <iostream>

class Point
{
    int x;
    int y;
public:
    Point( int a, int b) : x(a), y(b) // 초기화
    {
    //    x = a;    // 대입
    //    y = b;
    }
};

int main()
{
    Point p(1, 2);

    int a = 0; // 초기화. 생성자 호출
    
    int b;     // 생성자 호출
    b = 0;     // 대입. 대입연산자 호출
}

 

 

반드시 멤버 초기화 리스트를 사용해야 하는 경우

 

 - 클래스 안에 멤버 데이터가 const 또는 reference 로 되어 있을 때

 

#include <iostream>

class Point
{
    int x;
    int y;
    const int cval;   // const 변수
    int& r;
public:
    Point( int a, int b, int c) : x(a), y(b), cval(c), r(a)
    {
    //    cval = c; // 대입 : 에러 발생한다.
    //    x = a;    
    //    y = b;
    }
};

int main()
{
    Point p(1, 2, 10);
}

 

 

클래스 안에 디폴트 생성자가 없는 타입이 멤버 데이터로 있을 때 반드시 멤버 초기화 리스트를 사용해야 한다.

Point 의 경우 Point() 생성자가 없기 때문에 Rect(a,b,c,d)가 불렸을 때 p1, p2 멤버 초기화가 바로 되도록 아래 방식의 코딩이 되어야 한다.

 

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

class Rect
{
    Point p1;
    Point p2;
public:
    
    Rect(int a, int b, int c, int d) : p1(a,b), p2(c,d) // 무조건 이런 초기화가 좋다.
    {
        // if, switch와 같은 제어문에 의한 값 셋팅이 필요하다면 이곳에 초기화 해줘야함.
        //p1(a, b);  
    }
};

int main()
{
    Rect r (1,2,3,4);
            // p1 Point 생성자
            // p2 Point 생성자
            // Rect 생성자
}

 

 

주의사항:

초기화 순서는 멤버 데이타가 놓인 순서대로 초기화 된다.

즉, x가 먼저 초기화 되고, y 가 초기화 된다.

Pint() : y(0), x(y) 에서 y(0)가 먼저 수행되지 않는다. int x가 더 먼저 나와서 x가 먼저 초기화 된다.

 

#include <iostream>

class Point
{
public:
    int x;
    int y;

public:
    Point() : y(0), x(y)     // 잘못된 코딩이다!!!
    {
    }
};

int main()
{
    Point p;
    
    std::cout << p.x << std::endl; // 0 ???   컴파일러에 따라 주소값이 나올 수도 있다.
}

 

컴파일러마다 처리 방식이 달라서 주의해야 한다.

여기서 사용된 컴파일러는 문제없이 수행하여 0를 출력하고 있으나 조심해야 하는 부분이다.

 

 

 

 

 

댓글