Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ 범위 지정 연산자(::)와 this 포인터의 차이점 완벽 정리

C++ 프로그래밍에서 범위 지정 연산자(scope resolution operator, ::)this 포인터는 모두 클래스 멤버에 접근하는 데 사용되지만, 그 용도와 동작 방식은 서로 다릅니다. 이번 글에서는 몇 가지 예제 코드를 통해 두 기능이 어떤 상황에서 어떻게 사용되는지 살펴보겠습니다.

멤버 변수가 지역 변수에 가려지는 문제

클래스에 멤버 변수 x가 있고, 같은 이름 x를 매개변수로 받는 함수가 있다고 가정해 봅시다. 이 경우 함수 내부에서 x를 참조하면 멤버 변수는 가려지고(shadowing), 지역 변수인 매개변수가 대신 사용됩니다. 다음 예제를 통해 확인해 보겠습니다.

예제 코드

#include <iostream>
using namespace std;
class MyClass {
    private:
        int x;
    public:
        MyClass(int y) {
            x = y;
        }
    void myFunction(int x) {
        cout << "Value of x is: " << x;
    }
};
main() {
    MyClass ob1(10);
    ob1.myFunction(40);
}

실행 결과

Value of x is: 40

생성자를 통해 멤버 변수 x에 10을 저장했지만, 출력 결과는 40입니다. 이는 함수 내부에서 x를 참조할 때 멤버 변수가 아닌 매개변수 x가 우선적으로 사용되기 때문입니다.

this 포인터로 멤버 변수 접근하기

클래스의 멤버 변수 x에 접근하려면 this 포인터를 사용해야 합니다. this는 현재 객체 자신을 가리키는 특수한 포인터로, 멤버 변수와 매개변수의 이름이 충돌할 때 유용하게 활용됩니다.

예제 코드

#include <iostream>
using namespace std;
class MyClass {
    private:
        int x;
    public:
        MyClass(int y) {
            x = y;
        }
    void myFunction(int x) {
        cout << "Value of x is: " << this->x;
    }
};
main() {
    MyClass ob1(10);
    ob1.myFunction(40);
}

실행 결과

Value of x is: 10

이번에는 this->x를 사용했기 때문에 객체의 멤버 변수 값인 10이 올바르게 출력됩니다.

범위 지정 연산자와 this 포인터의 차이

C++에는 부모 클래스의 멤버나 정적(static) 멤버에 접근할 때 사용하는 범위 지정 연산자(::)가 있습니다. 중요한 점은 두 연산자의 용도가 서로 교환될 수 없다는 것입니다.

  • this 포인터: 현재 객체의 인스턴스 멤버에 접근할 때 사용
  • 범위 지정 연산자(::): 정적 멤버나 부모 클래스의 멤버에 접근할 때 사용

만약 위 예제처럼 인스턴스 멤버에 접근할 때 범위 지정 연산자를 사용하면 컴파일 오류가 발생합니다. 반대로 정적 멤버에 this 포인터를 사용하면 문제가 생길 수 있습니다. 정적 멤버는 특정 객체에 속하지 않고 클래스 전체에 공유되기 때문입니다.

예제 코드

#include <iostream>
using namespace std;
class MyClass {
    static int x;
    public:
        void myFunction(int x) {
            cout << "Value of x is: " << MyClass::x;
        }
};
int MyClass::x = 50;
main() {
    MyClass ob1;
    ob1.myFunction(40);
}

실행 결과

Value of x is: 50

위 예제에서 x는 정적 멤버 변수이므로 MyClass::x 형태로 접근했습니다. 결과적으로 정적 변수의 초기값인 50이 출력되며, 매개변수 x(40)와는 무관하게 동작합니다.

정리

이름 충돌이 발생하는 일반적인 인스턴스 멤버 변수에는 this 포인터를, 정적 멤버나 부모 클래스 멤버에는 범위 지정 연산자를 사용하는 것이 올바른 방법입니다. 두 도구의 역할을 명확히 구분하면 더 안전하고 가독성 높은 C++ 코드를 작성할 수 있습니다.