1. this 포인터

  • this 포인터(*this)는 class에 의해 생성된 실제 객체의 주소를 가리키는 포인터
  • *this를 통해 생성된 객체 자신의 멤버변수 및 멤버함수에 접근
  • 아래의 코드 PrintData() 함수에서 m_data에 접근하는 것은 실제 컴파일에서 this->m_data로 변환되어 컴파일
#include <iostream>
using namespace std;

class CMyData
{
private:
    int m_data;
public:
    CMyData(int nParam) : m_data(nParam)
    {

    }

    void PrintData()
    {
        // m_data 출력
        cout << m_data << endl;
        // CMyData 클래스의 멤버변수 m_data 출력
        cout << CMyData::m_data << endl;
        // 멤버함수를 호출한 인스턴스의 m_data 멤버 값 출력
        cout << `this->m_data` << endl;
        // 멤버함수를 호출한 인스턴스의 CMyData 클래스 멤버 m_data 출력
        cout << `this->CMyData::m_data` << endl;
    }

};

int main()
{
    CMyData a(5), b(10);
    a.PrintData();
    b.PrintData();

    return 0;
}
// 실행결과
// 5
// 5
// 5
// 5
// 10
// 10
// 10
// 10


2. 상수형 함수

  • 멤버함수에 const 키워드를 붙여 실수로 멤버변수를 변경하지 못하도록 사전에 방지
  • 상수화된 멤버함수는 멤버변수에 대한 읽기만 가능하도록 설정
  • 단, 멤버변수에 mutable 키워드가 선언되었을 경우 const 선언된 멤버함수에서도 멤버변수 값 변경 가능
#include <iostream>
using namespace std;

class CTest
{
private:
    int m_nData = 0;
    // `mutable` int m_nData = 0; <-- mutable 선언으로 값을 변경할 수 있음

public:
    CTest(int nParam) : m_nData(nParam) {}
    ~CTest(){}

    // 멤버함수 끝에 const 키워드를 입력하여 멤버변수에 대한 잘못된 변경을 사전에 방지한다.
    // 멤버함수에서 멤버변수에 대한 읽기 기능만 가능하도록 함
    int GetData() const
    {
        return m_nData;
    }

    int SetData(int nParam)
    {
        m_nData = nParam;
    }
};

int main()
{
    CTest test(10);
    cout << test.GetData() << endl;

    return 0;
}


3. 멤버함수 오버로딩

  • 동일 이름의 함수가 여러개 존재할 수 있음(2장 함수 오버로딩 내용 참고)
  • 함수 오버로딩의 조건(매개변수 개수가 달라야 함, 매개변수 type이 달라야 함)
  • 잘못된 함수 오버로딩 문법(Return type만 다른 경우)
  • delete 키워드를 통해 오버로딩 된 함수의 접근을 차단(컴파일 에러 발생)
    • ex) void SetData(double dParam) = delete;
#include <iostream>
using namespace std;

class CMyData
{
private:
    int m_nData;
public:
    CMyData(): m_nData(0){}
    int GetData()
    {
        return m_nData;
    }
    void SetData(int nParam) // 매개변수 type - int
    {
        m_nData = nParam;
    }

    void SetData(double nParam) // 매개변수 type - double
    {
        m_nData = 0;
    }

};

int main()
{
    CMyData a;

    // SetData(int) 함수 호출
    a.SetData(10);
    cout << a.GetData() << endl;

    CMyData b;
    // SetData(double) 함수 호출
    b.SetData(5.5);
    cout << b.GetData() << endl;

    return 0;
}


4. static 멤버

  • 일반적으로 class의 멤버함수(또는 멤버변수)에 접근하려면 객체 생성 후 접근
  • 그러나 객체 생성 없이 멤버함수(멤버변수)에 접근해야 할 때가 있음
  • 이 때 함수를 전역 위치에 선언하는 대신 class 멤버함수(멤버변수)로 구현한 뒤 static 키워드를 써줌
    • 전역함수(전역변수)와 동일한 효과를 얻을 수 있음
    • 전역 위치에 직접 구현한 것보다 안전하게 함수 및 변수를 사용할 수 있음
  • static 멤버에는 this 포인터 사용 불가능
// class 내부에서 멤버에 static 키워드 사용시 전역 선언처럼 사용 가능
// 전역변수, 전역함수로 만들어서 사용할 경우 발생할 수 있는 문제를 방지하기 위해 class 내부에 정의 후 static 선언!
// static 선언된 멤버는 객체 생성 없이 호출이 가능하다. (객체 생성 없이 특정 함수나 변수를 사용해야 할 때 활용)

#include <iostream>
using namespace std;

class CTest
{
private:
    int m_nData;

    // static 멤버변수 선언(정의는 하지 않음)
    static int m_nCount;

public:
    CTest(int nParam) : m_nData(nParam)
    {
        m_nCount++;
    }

    int GetData()
    {
        return m_nData;
    }

    void ResetCount()
    {
        m_nCount = 0;
    }

    // static 멤버함수 선언 및 정의
    static int GetCount()
    {
        return m_nCount;
    }
};

// class 내부에 선언된 static 멤버변수의 정의
// 중요: static 변수의 선언과 정의는 반드시 분리
int CTest::m_nCount = 0;

int main()
{
    CTest a(5), b(10);

    // static 멤버에 접근 (객체 생성 후 멤버에 접근한 경우)
    cout << a.GetCount() << endl;
    b.ResetCount();

    // 객체 생성 없이 class 내부에 선언된 멤버에 접근 가능
    cout << CTest::GetCount() << endl;

    return 0;
}


본 포스팅 내용은 이것이 C++이다를 학습한 내용을 바탕으로 요약한 글입니다. 코드에 문제가 있을 수 있으며 다소 부정확한 내용이 있을 수 있으니 참고하시기 바랍니다. 잘못된 내용이 있다면 덧글로 남겨주시면 내용을 반영하여 수정하도록 하겠습니다. 감사합니다.



[Reference]

[1] 이것이 C++이다, p.138-171