CPP 초급 강좌 27. 접근지정자, 캡슐화, friend 함수
앞에서 접근 지정자에 대한 언급이 조금 있었다. 이번에는 관련 내용을 조금 더 알아보자.
코드를 봅시다.
#include <iostream>
#include <string>
using namespace std;
class UserInfo
{
public:
string name = "";
int age = 0;
};
int main()
{
UserInfo newUserInfo;
newUserInfo.name = "신림83";
newUserInfo.age = 83;
}
유저 정보를 저장하기 위한 클래스를 선언하고, 유저 정보를 입력해 봅니다. 큰 문제가 없습니다. 하지만 실수로, 다음과 같이 코딩하면 어떻게 될까요?
newUserInfo.age = -83;
불가능한 일이 아닙니다. -가 실수로 타이핑될 수 있죠. 빌드 시에도 문제가 없습니다. 하지만 현실적으로 나이에 음수는 존재할 수 없죠. 이와 같이 변수에 대한 직접적인 접근은 문제가 될 가능성이 있는 경우가 분명 존재합니다. 이럴 때 접근 지정자를 사용하면 좋죠.
접근 지정자 적용
name, age를 외부에 공개하지 않고, 함수를 통해 초기화하도록 해봅시다. 그리고 음수 입력 시 체크하도록 코딩해보죠.
class UserInfo
{
private:
string name = "";
int age = 0;
public:
void Setup(string name, int age)
{
if (age < 1)
{
cout << "나이는 0 이하가 될수 없습니다." << endl;
return;
}
this->name = name;
this->age = age;
}
};
int main()
{
UserInfo newUserInfo;
//newUserInfo.name = "신림83";
//newUserInfo.age = 83;
newUserInfo.Setup("신림83", -83);
}
private 접근지정자를 사용하여 name, age를 정보은닉시켜 외부에서 접근하지 못하도록 하였습니다. 하지만 값은 넣어야겠죠. 그래서 public: 영역에 setup 함수를 만들어 값을 넣을 수 있게 하며, 만약 age가 음수로 들어올 경우 경고를 출력하게 한 코드입니다.
이와 같이 변수에 집적적인 접근보다는 함수로 set을 할 수 있게 구 한하는 것이 필요할 경우가 있습니다.
접근지정자는 3가지 종류가 있습니다.
private:
맴버 함수에서만 접근이 가능함
public:
맴버 함수가 아니라도 접근이 가능
protected:
자신과 상속된 관계에서만 접근이 가능함(아직 상속 관련 언급이 없으니 이런 게 있구나 정도로만...)
참고로 접근지정자를 선언하지 않을 시
struct 는 전 영역이 public:
class 는 전 영역이 private:
입니다.
용어에 대해 알아 두시면 좋습니다.
정보은닉
클래스를 설계하다 보면 순수하게 클래스 내부 작업을 위한 값들이 등장합니다. 이와 같은 값은 외부에서 알 필요가 없죠 이런 값들을 공개하지 않는 것을 정보은닉이라고 합니다.
캡슐화
위의 age와 같이 직접적인 접근이 아닌 함수를 통한 접근만을 허용합으로써 설계자는 값 입력에 대한 안정성을 확보할 수 있게 됨과 같은 방식을 캡슐화의 하나의 요소라고 보시면 될 거 같습니다. age를 setup이 싸고 있는 상태
setter / getter
각 내부 값들에 대한 설정과 접근을 하는 변수에 대하여 위의 용어를 많이 씁니다. 위의 setup은 setter의 요소를 가지고 있죠.
friend 함수
class UserInfo
{
private:
string name = "";
int age = 0;
public:
void Setup(string name, int age)
{
if (age < 1)
{
cout << "나이는 0 이하가 될수 없습니다." << endl;
return;
}
this->name = name;
this->age = age;
}
};
void fixName(UserInfo& userinfo, string newName)
{
userinfo.name = newName;
}
외부에서 fixName 이란 함수를 만들어서 이름을 수정하고 싶습니다. 내부 함수로 만들지 말고요. 이걸 구지 이렇게 만들어야 하나요 라고 생각하실 수 있죠. 그냥 지금은 이런 기능이 있구나 라고 봐주시면 좋겠네요.
위의 코드는 불가합니다. userinfo.name 정보은닉이 되어 있는 상태이기 때문이죠. 이럴 때 frined 함수를 사용하시면 해결하실 수 있습니다.
friend 함수 적용 코드
class UserInfo
{
private:
string name = "";
int age = 0;
public:
void Setup(string name, int age)
{
if (age < 1)
{
cout << "나이는 0 이하가 될수 없습니다." << endl;
return;
}
this->name = name;
this->age = age;
}
friend void fixName(UserInfo& userinfo, string newName);
};
void fixName(UserInfo& userinfo, string newName)
{
userinfo.name = newName;
}
설계한 클래스 내부에 friend void fixName(UserInfo& userinfo, string newName); 함수를 선언하였습니다. 해당 코드는 정상적으로 동작합니다.
사실 위의 예제는 동작은 하지만 올바른 코딩이라고 할 수 없습니다. 일단 기능적인 소개 정도라고 생각해주세요.
friend 함수 계념은 좀 더 복잡한 단계에서 분명 필요한 기능입니다. 이후에 언젠가 말할 기회가 있을 거예요.
봐주셔서 감사합니다.
'IT > C++(CPP)' 카테고리의 다른 글
CPP 초급 강좌 29. 맴버 초기화 리스트 member initializer lists (0) | 2020.11.10 |
---|---|
CPP 초급 강좌 28. 생성자 constructor (1) | 2020.11.09 |
CPP 초급 강좌 26. 객체 와 객체지향 프로그래밍 이란? (3) | 2020.11.05 |
CPP 초급 강좌 25. 객체지향 프로그램밍 클래스, 생성자, 소멸자, 파일분할, 클래스 탬플릿 (4) | 2020.11.04 |
CPP 초급 강좌 24. 객체지향 프로그램밍 객체화, 접근 지정자 맛보기 (9) | 2020.11.03 |
댓글