Encapsulation

캡슐화(Encapusulation)
객체 지향 프로그래밍 기법에서 중요한 키워드이다.
캡슐화의 기본 원리는 관련된 함수와 멤버들을 되도록 하나의 클래스에서 관리하는 것이다.
실행되어야 하는 기능들도 하나의 클래스에 넣어서 각 객체가 응집된 기능을 가질 수 있도록 한다.
프렌드
기본적으로 C++에서 멤버 변수에 접근하기 위해서는 public 멤버 함수를 이용해야 한다.
다만 특정한 객체의 멤버 함수가 아닌 경우 private 멤버에 접근해야 할 때가 있다.
이 때 프렌드(friend) 키워드를 이용하면 특정한 객체의 모든 멤버에 접근 가능하다.
friend 함수

friend Student operator +(const Student& sutdent, const Student& other)
#include <iostream>
#include <string>
using namespace std;
class Student{
private:
int studentId;
string name;
public:
Student(int studentId, string name):studentId(studentId), name(name) {}
friend Student operator +(const Student& student, const Student& other){
return Student(student.studentId, student.name+" & "+other.name);
}
void showName(){ cout<<": "<<name<<'\n';}
};
int main(void){
Student student(1, "");
Student result=student+student;
result.showName();
system("pause");
return 0;
}
위의 2가지 피 연산자를 위한 전역함수는 내장 타입에 대하여 오버로딩을 할 수 없기 때문에
연산자 전역 함수를 이용해서 연산자 오버로딩을 진행한다.

위의 예시에서는 friend를 굳이 사용할 필요가 없다 (friend for overloading 참조)
friend 클래스
프렌드 클래스에서는 모든 멤버 함수가 특정 클래스의 프렌드이다.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
class Time{
friend class Date;
private:
int hour, min, sec;
public:
void setCurrentTime(){
time_t currentTime=time(NULL);
struct tm *p=localtime(&currentTime);
hour=p->tm_hour;
min=p->tm_min;
sec=p->tm_sec;
}
};
class Date{
private:
int year, month, day;
public:
Date(int year, int month, int day) :year(year), month(month), day(day) {}
void show(const Time& t){
cout<<" : "<<year<<" "<<month<<" "<<day<<""<<'\n';
cout<<" : "<<t.hour<<":"<<t.min<<":"<<t.sec<<'\n';
}
};
int main(void){
Time time;
time.setCurrentTime();
Date date=Date(2021, 06, 26);
date.show(time);
system("pause");
return 0;
}
정적 멤버(Static Member)
클래스에는 포함되어 있는 멤버이지만, 모든 객체가 공유하는 멤버이다.
정적으로 선언된 멤버는 메모리 상에 오직 하나만 할당되어 관리된다.

정적멤버를 public으로 선언하면 외부의 어떠한 클래스에서 접근이 가능하며, 오직 하나만 관리된다.
정적 멤버는 일반적으로 싱글톤 패턴(Singleton Pattern)등의 다양한 기능을 위해 사용된다.

static int count;
int Person :: count=0;        외부에서 static 변수 초기화
#include <iostream>
#include <string>
using namespace std;
class Person{
private:
string name;
public:
static int count;
Person(string name):name(name){
count++;
}
};
int Person :: count=0;
int main(void){
Person p1("");
Person p2("");
Person p3("");
cout<<" : "<<Person::count<<'\n';
system("pause");
return 0;
}
상수 멤버(Const Member)
상수 멤버는 호출된 객체의 데이터를 변경할 수 없는 멤버이다.

const int id;
#include <iostream>
#include <string>
using namespace std;
class Person{
private:
const int id;
string name;
public:
static int count;
Person(int id, string name):id(id), name(name){
count++;
}
/*
void setId(int id){
this->id=id; // [ ]
}
*/
};
int Person::count=0;
int main(void){
Person p1(1,"");
Person p2(2,"");
Person p3(3,"");
cout<<" : "<<Person::count<<'\n';
system("pause");
return 0;
}