본문 바로가기
IT/C++(CPP)

CPP 초급 강좌 27. 접근지정자, 캡슐화, friend 함수

by 신림83 2020. 11. 6.
반응형

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 함수 계념은 좀 더 복잡한 단계에서 분명 필요한 기능입니다. 이후에 언젠가 말할 기회가 있을 거예요.

 

 

공부합시다.

봐주셔서 감사합니다.

반응형

댓글