이번에는 캡슐화에 관한 문법 중에 멤버의 가시성을 설정하는 접근 지정자를 살펴보아요.
이번에는 멤버의 가시성을 설정하는 접근 지정자에 관해 알아볼게요.
C언어의 구조체는 모든 곳에서 모든 멤버를 접근할 수 있어요. 이러한 특징은 개발자가 멤버에 접근하기 쉬워서 구현하기 쉽게 생각할 수 있지만 시나리오에 맞게 데이터를 유지하는 것은 어려울 수 있어요.
예를 들어 설명할게요.
프로그램에서 이름, 번호, 아이큐를 멤버로 갖는 학생 형식이 있다고 가정합시다.
학생 개체는 생성할 때 이름과 번호를 부여하고 아이큐는 100으로 설정하기로 해요. 그리고 학생이 공부하면 아이큐가 공부한 시간만큼 증가하게 만들거예요. 단 아이큐는 300을 넘지 않게 하기로 해요.
그런데 학생 개체를 사용하는 곳에서 학생 구조체의 멤버에 접근할 수 있어서 “공부하다.” 기능을 호출하지 않고 직접 아이큐를 조절하면 범위를 벗어날 수 있어요. 이와 같은 버그가 발생하였을 때 이를 발견하고 수정하는데 비용이 발생하겠죠.
//Student.h
#pragma once
#define MAX_NAME_LEN 20
#define DEF_IQ 100 //디폴트 IQ
#define MAX_IQ 300 //최대 IQ
typedef struct Student Student;
struct Student
{
int num;
char name[MAX_NAME_LEN];
int iq;
};
void Student_Student(Student *stu,int num, const char *name); //생성자
void Student_Study(Student *stu, int hours);//공부하다.
void Student_View(Student *stu);//학생 정보 출력
//Student.c
#include "Student.h"
#include <string.h>
#include <stdio.h>
void Student_Student(Student *stu,int num, const char *name)
{
stu->num = num;
strcpy_s(stu->name,MAX_NAME_LEN,name);
stu->iq = DEF_IQ;
}
void Student_Study(Student *stu, int hours)
{
printf("%s 학생 %d시간 공부하다.\n",stu->name, hours);
if( stu->iq + hours >MAX_IQ)
{
stu->iq = MAX_IQ;
}
else
{
stu->iq += hours;
}
}
void Student_View(Student *stu)
{
printf("번호:%d, 이름:%s, 아이큐:%d\n",stu->num,stu->name,stu->iq);
}
//Program.c
#include "Student.h"
int main()
{
Student stu;
Student_Student(&stu,34,"홍길동");
Student_View(&stu);
Student_Study(&stu,50);
Student_View(&stu);
stu.iq += 300; //멤버에 직접 접근하여 값을 설정
Student_View(&stu);
return 0;
}
▷실행 결과
번호:34, 이름:홍길동, 아이큐:100
홍길동 학생 50시간 공부하다.
번호:34, 이름:홍길동, 아이큐:150
번호:34, 이름:홍길동, 아이큐:450
위 예제에서 main 함수에서 직접 학생의 멤버 iq에 접근하여 설정하지 않고 Student_Study 함수를 사용했다면 학생의 IQ는 최대값을 넘지 않아요. 결국 C언어에서는 어디에서나 구조체의 멤버에 접근할 수 있어서 발생한 버그예요.
C++언어에서는 멤버의 가시성을 설정하는 접근 지정자 문법을 제공하고 있어요.
class 정의할 때 private, protected, public 키워드와 콜론(:)을 지정하여 이 후의 작성한 멤버의 가시성을 설정할 수 있어요.
private 접근 지정은 형식 내부에서만 접근할 수 있습니다.
public은 모든 곳에서 멤버에 접근할 수 있습니다.
protected는 파생 형식에서도 접근할 수 있습니다. 이 부분은 상속을 다루면서 설명하기로 해요.
클래스는 디폴트 가시성이 private이고 구조체는 public입니다.
class Student
{
int num;
string name;
int iq;
public:
Student(int _num,string _name);
void Study(int hour);
void View();
};
클래스의 디폴트 접근 지정은 private입니다. 위처럼 정의하면 num과 name, iq는 디폴트로 접근 지정합니다.
그리고 public: 지정한 뒤에 세 개의 멤버는 접근 지정이 public입니다.
따라서 형식 외부에서 num, name, iq 멤버에 접근할 수 없어요.
다음의 코드는 C++언어에서 접근 지정을 통해 신뢰성을 강화한 코드입니다. 멤버 iq의 접근 지정을 디폴트인 private으로 설정하여 형식 외부에서 접근할 수 없게 만들었어요.
아직 멤버 메서드 캡슐화를 다루지 않은 상태여서 모두 이해할 수는 없지만 코드를 한 번 보시고 따라서 작성 및 분석해 보세요.
//Student.h
#pragma once
#include <string>
using namespace std;
#define DEF_IQ 100 //디폴트 IQ
#define MAX_IQ 300 //최대 IQ
class Student
{
int num;
string name;
int iq;
public:
Student(int _num,string _name);
void Study(int hour);
void View();
};
//Student.cpp
#include "Student.h"
#include <iostream>
using namespace std;
Student::Student(int _num,string _name)
{
num = _num;
name = _name;
iq = DEF_IQ;
}
void Student::Study(int hour)
{
cout<<name<<" 학생 "<<hour<<"시간 공부하다."<<endl;
if( iq + hours >MAX_IQ)
{
iq = MAX_IQ;
}
else
{
iq += hours;
}
}
void Student::View()
{
cout<<"번호:"<<num<<", 이름:"<<name<<", 아이큐:"<<iq<<endl;
}
//Program.cpp
#include "Student.h"
int main()
{
Student stu(34,"홍길동");
stu.View();
stu.Study(50);
stu.View();
//stu.iq += 300; //private 접근 지정한 멤버는 형식 외부에서 접근 못 함
stu.View();
return 0;
}
▷실행 결과
번호:34, 이름:홍길동, 아이큐:100
홍길동 학생 50시간 공부하다.
번호:34, 이름:홍길동, 아이큐:150
번호:34, 이름:홍길동, 아이큐:150
'언어 자료구조 알고리즘 > 디딤돌 C++' 카테고리의 다른 글
20. 캡슐화 실습1 - 복소수 (2) | 2016.01.27 |
---|---|
19. 특별한 멤버 this (0) | 2016.01.27 |
18. 상수화 멤버 (0) | 2016.01.27 |
17. 정적(static) 멤버 (0) | 2016.01.27 |
16. 생성자, 소멸자 (0) | 2016.01.27 |
14. 캡슐화 개요 (0) | 2016.01.27 |
13. OOP 개요 (0) | 2016.01.27 |
12. string 형식 개요 (0) | 2016.01.27 |
11. 논리 형식 bool 제공 (0) | 2016.01.27 |
10. 신뢰성 강화 (열거형) (0) | 2016.01.27 |