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

C++ 접근 지정자(Access Modifier) 완벽 정리: public, private, protected

접근 지정자(Access Modifier)는 객체 지향 프로그래밍에서 데이터 은닉(data hiding)을 구현하기 위해 사용되는 핵심 도구입니다. 클래스 외부에서 내부 데이터에 함부로 접근하지 못하도록 통제함으로써, 코드의 안정성과 캡슐화를 보장할 수 있습니다.

C++에는 세 가지 접근 지정자가 존재하며, 각각 다음과 같은 특징을 가집니다.

  • public — 어디서든 접근 가능
  • private — 클래스 내부에서만 접근 가능
  • protected — 클래스 내부와 파생(자식) 클래스에서 접근 가능

아래에서 각 접근 지정자를 예제 코드와 함께 자세히 살펴보겠습니다.

1. public 접근 지정자

public으로 선언된 데이터 멤버와 멤버 함수는 프로그램의 어디에서나 접근할 수 있습니다. 다른 클래스에서도 접근이 가능하며, 클래스 객체와 점(.) 연산자를 사용하면 언제든 호출할 수 있습니다.

예제 코드

#include<iostream>
using namespace std;
class Add {
    public:
    int a, b;
    void sum() {
        cout<<"Sum of "<< a <<" and "<< b <<" is "<<a+b;
    }
};
int main() {
    Add obj;
    obj.a = 2;
    obj.b = 5;
    obj.sum();
    return 0;
}

실행 결과

Sum of 2 and 5 is 7

위 프로그램에서 Add 클래스는 두 개의 public 데이터 멤버 ab를 가지고 있으며, 멤버 함수 sum()은 이 두 값의 합을 출력합니다.

class Add {
    public:
    int a, b;
    void sum() {
        cout<<"Sum of "<< a <<" and "<< b <<" is "<<a+b;
    }
};

main() 함수 안에서 Add 클래스의 객체를 생성한 뒤, ab에 직접 값을 대입합니다. 이것이 가능한 이유는 두 변수가 public으로 선언되어 클래스 외부에서도 접근할 수 있기 때문입니다. 마지막으로 sum()을 호출하여 합계를 출력합니다.

Add obj;
obj.a = 2;
obj.b = 5;

obj.sum();

2. private 접근 지정자

private으로 선언된 데이터 멤버는 클래스 내부의 멤버 함수에서만 접근할 수 있습니다. 클래스 외부의 어떤 함수도 직접 접근할 수 없으며, 예외적으로 프렌드(friend) 함수만이 private 멤버에 접근할 수 있습니다.

예제 코드

#include<iostream>
using namespace std;
class Add {
    private:
    int a, b;
    public:
    void setdata(int x, int y) {
        a = x;
        b = y;
    }
    void sum() {
        cout<<"Sum of "<< a <<" and "<< b <<" is "<<a+b;
    }
};
int main() {
    Add obj;
    obj.setdata(9,5);
    obj.sum();
    return 0;
}

실행 결과

Sum of 9 and 5 is 14

위 프로그램에서 Add 클래스의 ab는 private 변수로 선언되었습니다. 따라서 외부에서 직접 값을 설정할 수 없으며, 대신 public 멤버 함수인 setdata()를 통해 값을 초기화해야 합니다. sum()은 두 값의 합을 출력합니다.

class Add {
    private:
    int a, b;
    public:
    void setdata(int x, int y) {
        a = x;
        b = y;
    }
    void sum() {
        cout<<"Sum of "<< a <<" and "<< b <<" is "<<a+b;
    }
};

main() 함수에서는 객체를 생성한 후, private 변수인 ab를 초기화하기 위해 반드시 setdata()를 호출해야 합니다. 만약 obj.a = 9;처럼 직접 접근하려 하면 컴파일 오류가 발생합니다. 이후 sum()을 호출하여 결과를 출력합니다.

Add obj;
obj.setdata(9,5);
obj.sum();

3. protected 접근 지정자

protected로 선언된 데이터 멤버는 private과 매우 유사하게 동작합니다. 클래스 외부에서는 직접 접근할 수 없지만, 결정적인 차이점은 기반(base) 클래스의 파생(derived) 클래스에서 접근할 수 있다는 것입니다. 상속 관계에서 유용하게 활용됩니다.

예제 코드

#include<iostream>
using namespace std;
class Parent {
    protected:
    int a, b;
};
class Child: public Parent {
    public:
    void getdata(int x, int y) {
        a=x;
        b=y;
    }
    void putdata() {
        cout<<"a = "<<a<<endl;
        cout<<"b = "<<b<<endl;
    }
};
int main() {
    Child obj;
    obj.getdata(9,1);
    obj.putdata();
    return 0;
}

실행 결과

a = 9
b = 1

위 프로그램에서 부모 클래스인 Parent는 두 개의 protected 변수 ab를 가지고 있습니다.

class Parent {
    protected:
    int a, b;
};

자식 클래스인 Childgetdata()putdata()라는 두 개의 함수를 통해 ab의 값을 각각 설정하고 출력합니다. 이것이 가능한 이유는 ab가 protected 변수이고, ChildParent의 파생 클래스이기 때문입니다. 만약 Child가 아닌 외부 코드에서 접근했다면 컴파일 오류가 발생했을 것입니다.

class Child: public Parent {
    public:
    void getdata(int x, int y) {
        a = x;
        b = y;
    }
    void putdata() {
        cout<<"a = "<<a<<endl;
        cout<<"b = "<<b<<endl;
    }
};

main() 함수에서는 Child 클래스의 객체 obj를 생성한 후, getdata()로 값을 설정하고 putdata()로 출력합니다.

Child obj;
obj.getdata(9,1);
obj.putdata();

마무리: 세 가지 접근 지정자 비교

접근 지정자클래스 내부파생 클래스클래스 외부
publicOOO
protectedOOX
privateOXX

적절한 접근 지정자를 선택하는 것은 캡슐화를 실현하고 안전하고 유지보수하기 좋은 C++ 코드를 작성하는 첫걸음입니다. 기본적으로는 멤버 변수를 private 또는 protected로 숨기고, 필요한 인터페이스만 public으로 노출하는 것이 권장됩니다.