Programming/프로그래밍언어 공부

접근지정자 private, protect, public 비교

choiyeong 2025. 4. 13. 18:03

요약

private : 해당 클래스 내부에서만 접근 가능.

protect : 해당 클래스 및 상속받은 클래스에서만 접근 가능

public : 어디서든 접근가능

접근 가능하다란? 수정 및 인용이 가능하다는 뜻.

사용 이유

근원을 알 수 없는 곳에서 값을 수정해버리는 현상을 방지하기 위함.

 

아래의 작성된 코드로 예시를 들어보겠다.

//클래스 공부
#include <iostream>

using namespace std;

//캐릭터 클래스
class Character {
private:
    string name;
    int level;
    int item_num;
public:
    Character(string a, int b, int c) {
        name = a;
        level = b;
        item_num = c;
        cout << "캐릭터 생성 완료! 캐릭터명 : " << name << endl;
    }

    void showInfo() {
        cout << "캐릭터명 : " << name << endl;
        cout << "레벨 : " << level << endl;
        cout << "아이템 개수 : " << item_num << endl;
    }
    void levelUp() {
        level++;
        cout << "레벨업! 현재 레벨 : " << level << endl;
    }
    void addItem() {
        item_num += 1;
        cout << "아이템 추가! 현재 아이템 개수 : " << item_num << endl;
    }
    void removeItem(int num) {
        if (item_num >= num) {
            item_num -= num;
            cout << "아이템 사용! 현재 아이템 개수 : " << item_num << endl;
        }
        else {
            cout << "아이템이 부족합니다!" << endl;
        }
    }
    void changeName(string newName) {
        name = newName;
        cout << "이름 변경 완료! 현재 캐릭터명 : " << name << endl;
    }
};

int main() {
    string name;
    cout << "캐릭터를 생성합니다." << endl;
    cout << "캐릭터 이름은? : ";
    cin >> name;
    Character me(name, 0, 0);
    int act=0;
    while (act!=6){
        cout << "무엇을 하시겠습니까? \n1. 이름 변경 \n2. 레벨업 \n 3.아이템 줍기 \n4. 아이템사용 \n5. 캐릭터 정보 보기 \n6. 종료" << endl;
        cin >> act;
        if (act == 1) {
            cout << "변경할 이름은? : ";
            cin >> name;
            me.changeName(name);
        }
        else if (act == 2) {
            me.levelUp();
        }
        else if (act == 3) {
            me.addItem();
        }
        else if (act == 4) {
            int item_num;
            cout << "사용할 아이템 개수는? : ";
            cin >> item_num;
            me.removeItem(item_num);
        }
        else if (act == 5) {
            me.showInfo();
        }
        else if (act == 6) {
            cout << "종료합니다." << endl;
        }
        cout << "------------------------" << endl;
        cout << endl;
        cout << "------------------------" << endl;
    }
    return 0;
}

Character 클래스는 이름,레벨,아이템을 private 변수로 갖고 있다.

만약 이를 public 변수로 갖고 있다면 어떤 현상이 일어나는가?

 

외부에서 me.name="이름변경"; 이런식으로 간단하게 이름이 변경 되어버린다.

마찬가지로 me.level = 99; 이렇게 사용자에게 레벨 조작도 쉽게 되어서 데이터가 망가질 가능성이 커진다.

이를 방지하고자 private로 외부에서 접근할 수 없거나 접근할 필요가 없는 변수,데이터들을 은닉하는 것을 캡슐화(Encapsulation)라고 한다.

 

그럼 level을 변경하기 위해선 public으로 levelUp() 메서드를 거쳐야만 한다.

levelUp()메서드를 거쳐야만 level을 변경가능하므로 데이터보호 필터링이 가능하다는 장점이 있다.

이처럼 함부로 값이 변하면 안되는 변수는 private로 지정하여 보호하고, 값이 변해야하는 상황을 메서드로 설정하여 기능을 안전하게 구현할 수 있다.

 

예시코드에 protect가 없는데 이에 대한 설명을 좀 더 추가하자면

우리가 몬스터를 사냥할 때 자주 측정하는 공격력이 있다. 이 공격력을 캐릭터의 기본 스텟과 무기의 스텟에 따라 바뀌는데 만약 private로 attactPoint를 설정한다면 매번 모든 무기마다 데미지를 계산하기 위해 damage()라는 메서드로 매번 attactPoint를 가져와야한다. 번거롭다면 번거롭고 처리속도도 느려지기 떄문에 그냥 힘스텟을 protect로 접근지정자를 두어 공격이 적중될때 데미지를 계산하려면 힘에 대한 변수를 그대로 사용하면 된다.

 

즉, protect 접근지정자는 private해야하는 변수지만 특별한 상황에는 public해야하는 상황에 사용할 때 쓰인다.