KoreanFoodie's Study

C++ 기초 개념 4-4 : 생성자 초기화 리스트, static 변수, this 포인터, const 멤버 함수 본문

Tutorials/C++ : Beginner

C++ 기초 개념 4-4 : 생성자 초기화 리스트, static 변수, this 포인터, const 멤버 함수

GoldGiver 2021. 12. 20. 19:48

모두의 코드를 참고하여 핵심 내용을 간추리고 있습니다. 자세한 내용은 모두의 코드의 씹어먹는 C++ 강좌를 참고해 주세요!

생성자의 초기화 리스트(initializer list)

간단한 예시 코드를 보자.

class Test {
    int a;
    int b;
    Test();
}

Test::Test() : a(1), b(2) {}

위의 예시에서, (생성자 이름) : var1(arg1), var2(arg2) ... 같은 형식을 써 주면, 생성자 호출과 동시에 멤버 변수들을 초기화해줄 수 있다.

"동시에"라는 개념이 중요하다. 초기화 리스트를 사용하지 않으면 생성을 먼저 하고 그 다음에 대입을 수행하게 된다. 따라서, 초기화 리스트는

int a = 10;

와 같고, 일반 버전의 생성자는

int a;
a = 10;

처럼 작동한다. 만약에 int 가 클래스였다면, 전자의 경우 복사 생성자가 호출되는데, 후자의 경우 디폴트 생성자가 호출된 후에 대입이 수행된다.

따라서 초기화 리스트를 사용하는 것이 조금 더 효율적이다. 또한, 레퍼런스와 상수처럼, '생성과 동시에 초기화되어야 하는 것들'이 있다.

 

상수와 레퍼런스는 생성과 동시에 초기화가 되어야 한다.

class Test {
    const int a;
    Test();
}

// C++ 11 에서는 클래스 외부에서 초기화를 해준다.
Test::Test() : a(5) {}; 

// C++ 17 이후부터는 클래스 내부에서 초기화가 가능하다.
// const int a = 5;

 

 

static 변수

클래스 하나에만 종속되는 변수를 static 멤버 변수라고 한다. static 멤버 변수는 모든 객체들이 '공유'하는 변수이다. 예를 들어, 생성된 객체들의 갯수를 셀 때, static 멤버 변수를 활용하면 쉽게 구할 수 있다.

class Test {
    static int num_obj;
    Test();
    ~Test();
}

int Test::num_obj = 0; // 객체 갯수를 0으로 초기화
Test::Test() : { ++num_obj; }
Test::~Test() : { --num_obj; }

 

 

this 키워드

this는 객체 자신을 가리키는 포인터의 역할을 한다. 따라서 모든 멤버 함수 내에서는 this 키워드가 정의되어 있으며, 클래스 안에서 정의된 함수 중에서 this 키워드가 없는 함수는 static 함수 뿐이다.

 

 

레퍼런스를 리턴하는 함수

class A {
    int x;
public:
    A(int c) : x(c) {}
    int& access_x() { return x; }
    int get_x() {return x; }
};

int main() {
    A a(5);
    
    int& c = a.access_x();
    c = 4;
    
    int& d = a.get_x(); // 오류
    d = 4;
    
    int e = a.access_x();
    e = 3;
}

c의 경우, 레퍼런스를 받았으므로, a의 x를 레퍼런스로 받은 것이다. 따라서 int& c = a.x; 와 같다. 따라서 a.x의 값이 4로 바뀐다.

반면 d의 경우, a.get_x()가 값을 리턴하므로, 이를 레퍼런스로 받을 수가 없다. 임시객체의 레퍼런스를 받을 수 없는 것이다.

e의 경우, e가 그냥 int 변수이므로, 값의 복사가 일어나 e에는 x의 값이 들어간다. 따라서, a.x의 값이 바뀌지 않는다.

 

우리는 이제 아래와 같은 코드를 제대로 이해할 수 있다.

Test& Test::ItSelfAsReference() {
    return *this;
}

this는 객체를 가리키는 포인터이고, *this는 객체 자체이므로, 이를 레퍼런스로 넘겨 이후 해당 객체를 조작할 수 있도록 만드는 것이다.

 

 

상수 함수 (const 함수)

C++에서는 변수들의 값을 바꾸지 않고 읽기만 하는, 마치 상수 같은 멤버 함수를 상수 함수로 선언할 수 있다.

Test::Test get_a const { return this->a; }

const는 클래스 내부 멤버 변수들의 값을 바꾸지 않는다는 것을 보장한다.

Comments