6.1 접근 지정자
접근지정자
캡슐화의 목적
- 객체 보호, 보안
- C++에서 객체의 캡슐화 전략
- 객체의 상태를 나타내는 데이터 멤버(멤버 변수)에 대한 보호
- 중요한 멤버는 다른 클래스나 객체에서 접근할 수 없도록 보호
- 외부와의 인터페이스를 위해서 일부 멤버는 외부에 접근 허용
멤버에 대한 3가지 접근 지정자
- private: 디폴트
- 동일한 클래스의 멤버 함수에만 제한함
- 클래스 밖에서 직접 접근 불가
- protected
- 클래스 자신과 상속받은 자식 클래스에만 허용
- public
- 모든 다른 클래스에 허용, 클래스 밖에서 직접 접근 가능
class Sample{
private:
// private 멤버 선언
protected:
// protected 멤버 선언
public:
// public 멤버 선언
};
접근 지정자 | 해당 클래스의 멤버함수에서의 접근 |
파생클래스의 멤버함수에서에의 접근 |
클래스 밖에서의 접근 |
private | O | X | X |
protected | O | O | X |
public | O | O | O |
- 클래스 안: 클래스 정의의 내부와 멤버 함수의 구현
- 클래스 밖: 전역 함수 정의나 다른 클래스의 정의, 클래스로 만들어진 객체
멤버의 접근 지정에 따른 접근성
중복 접근 지정과 디폴트 접근 지정
접근 지정 중복
class Sample{
private:
int x, y;
public:
Sample();
private:
bool checkXY();
};
디폴트 접근 지정: private
class Circle{
int radius;
public:
Circle();
Circle(int r);
double getArea();
};
*/
위 코드와 같다.
class Circle{
private:
int radius;
public:
Circle();
Circle(int r);
double getArea();
};
*/
C++ 구조체
C++ 구조체
- 상속, 멤버, 접근 지정 등 모든 것이 클래스와 동일
- 클래스와 유일하게 다른 점
- 구조체의 디폴트 접근 지정 - public
- 클래스의 디폴트 접근 지정 - private
struct StructName{
private:
// private 멤버 선언
protected:
// protected 멤버 선언
public:
// public 멤버 선언
};
C++에서 구조체를 수용한 이유?
- C++언어와의 호환성 때문
- C의 구조체 100% 호환 수용
- C 코드를 그대로 가져다 쓰기 위해
구조체 객체 생성
- struct 키워드 생략
StructName stObj; // (O) C++ 구조체 객세 생성
struct StructName Obj; // (X) C 언어의 구조체 객체 생성
구조체와 클래스의 디폴트 접근 지정 비교
// 구조체에서 디폴트 접근 지정은 public
struct Circle{
Circle();
Circle(int r);
double getArea();
private:
int radius;
};
// 클래스에서 디폴트 접근 지정은 private
class Circle{
int radius;
public:
Circle();
Circle(int r);
double getArea();
};
접근자 함수(accessor function)
접근자 함수
- public 접근 권한을 갖는 멤버 함수
- 클래스의 멤버 변수에 대한 접근을 도와주는 기능 제공
- 접근자 함수는 보통 get 함수(값 리턴)와 set 함수(값 설정)로 구현됨
class Sample{
int mem;
public:
int getMem();
void setMem(int value);
};
// get 함수
int Sampel::getMem(){
return mem;
}
// set 함수
void Sample::setMem(int value){
mem = value;
}
접근자 함수의 장점
다양한 레벨의 접근 권한 설정 가능
- 멤버 변수를 public으로 지정하면 클래스 밖에서 멤버 변수에 대한 모든 접근을 허용하게 된다.
- 접근자 함수를 사용할 때는 get 함수만 정의할 수 있고, set 함수만 정의할 수도 있고, get/set 함수를 모두 정의할 수도 있고, get/set 함수를 모두 정의하지 않을 수도 있다.
멤버 변수의 값을 변경하거나 읽어올 때, 멤버 변수의 값에 대한 유효성 검사 가능
bool Circle::setRadius(int r){
if(r > 30) return false;
radius = r;
return true;
}
6.2 const 객체와 const 멤버함수
const 객체
const 객체
멤버 변수의 값을 변경할 수 없음
- const 객체에는 대입할 수 없음
Circle pizza1(5);
const Circle pizza2; // 디폴트 생성자로 초기화
pizza2 = pizza1; // const 객체에는 대입할 수 없으므로 컴파일 에러
- const 멤버 함수만 호출 가능 -> const 멤버 함수를 지정할 필요가 있다.
const 객체의 사용
- 객체를 함수의 입력 인자로 전달할 때 주로 사용
void ShowData(Circle& s);
void ShowData(const Circle& s); // s는 입력 인자, 원본 데이터를 변경할 수 없음을 보장
const 객체 사용 예
class CellPhone
{
public:
int bell_mode;
void Call(int quick_num);
// const 멤버 함수라는 뜻. 함수 내에서 멤버 변수를 못바꾼다는 것을 보장
void ShowRecentCall() const;
};
void main()
{
const CellPhone myPhone;
myPhone.bell_mode = 3; // 오류
myPhone.Call(1); // 오류
// const 객체는 const 멤버 함수만 호출할 수 있다
myPhone.ShowRecentCall();
}
const 멤버 함수
객체의 값을 변경하지 않기로 약속하는 멤버 함수
- "이 함수에서는 멤버 변수의 값을 변경하지 않으므로, const 객체가 이 멤버함수를 호출해도 안전하다."는 의미
- 클래스의 사용자에게 멤버 함수에 대한 명확한 정보를 제공
const 멤버 함수로 지정하는 방법
- 함수의 선언과 정의 양쪽 모두에 const 키워드 지정
class 클래스 이름{
멤버 함수 선언 const;
};
리턴형 클래스이름:: 멤버함수이름(인자리스트) const
{
}
const 멤버 함수 안에서는
- 멤버 변수의 값 변경 불가능 / 디른 일반 멤버 함수 호출 불가능
const 멤버 함수의 의미
- 멤버 함수를 const로 만드는 것의 의미
- 다른 개발자가 "이 함수는 멤버 변수의 값을 변경하지 않는구나" 라고 생각하게 만든다.
- 실수로 멤버 변수의 값을 바꾸려고 하면 컴퓨터가 오류 메시지를 통해서 알려준다.
- const 객체를 사용해서 이 함수를 호출할 수 있다.
번외) const를 왜 뒤에다 붙일까? -> 앞에다 붙이면 리턴 타입에 const가 적용되는 것으로 되기 때문
6.3 static 멤버
static 멤버와 non-static 멤버의 특성
static
- 변수와 함수에 대한 기억 부류의 한 종류
- 생명 주기 - 프로그램이 시작될 때 생성, 프로그램 종료 시 소멸
- 사용 범위 - 선언된 범위, 접근 지정에 따름
클래스의 멤버
- static 멤버
- 프로그램이 시작할 때 생성
- 클래스 당 하나만 생성, 클래스 멤버라고 불림
- 클래스의 모든 인스턴스(객체)들이 공유하는 멤버
- non-static 멤버
- 객체가 생성될 때 함께 생성
- 객체마다 객체 내에 생성
- 인스턴스 멤버라고 불림
static 멤버선언
멤버의 static 선언
class Person{
public:
double money;
void addMoney(int money){
this->money += money;
}
static int sharedMoney; // static int sharedMoney = 10; (X)
static void addShared(int n){
sharedMoney += n;
}
};
// static 변수 공간 할당, 프로그램의 전역 공간에 선언
// 선언하면 다음과 같이 정의(초기화)가 반드시 필요
int Person::sharedMoney = 10;
// static 멤버 변수는 생성자로 초기화 못한다.
// 객체로도 접근되고, 클래스로도 접근 가능
static 멤버 변수 생성
- 전역 변수로 생성. 전체 프로그램 내에 한 번만 생성
static 멤버 변수에 대한 외부 선언이 없으면 다음과 같은 링크 오류
static 멤버와 non-static 멤버의 관계
static 멤버 함수 안에서는 non-static 멤버 사용 불가능
static 멤버와 non-static 멤버 비교
항목 | non-static 멤버 | static 멤버 |
선언 사례 | class Sample{ int n; void f(); }; |
class Sample{ static int n; static void f(); }; |
공간 특성 | 멤버는 객체마다 별도 생성 - 인스턴스 멤버라고 부름 |
멤버는 클래스 당 하나 생성 - 멤버는 객체 내부가 아닌 별도의 공간에 생성 - 클래스 멤버라고 부름 |
시간적 특성 | 객체와 생명을 같이 함 - 객체 생성 시에 멤버 생성 - 객체 소멸 시에 함께 소멸 - 객체 생성 후 객체 사용 가능 |
프로그램과 생명을 같이 함 - 프로그램 시작 시 멤버 생성 - 객체가 생기기 전에 이미 존재 - 객체가 사라져도 여전히 존재 - 프로그램이 종료될 때 함께 소멸 |
공유의 특성 | 공유되지 않음 - 멤버는 객체 별로 따로 공간 유지 |
동일한 클래스의 모든 객체들에 의해 공유됨 |
static 멤버 사용: 객체의 멤버로 접근
정적 멤버 변수
- 같은 클래스의 객체들 사이에 공유되는 멤버 변수
- 보통 멤버처럼 접근할 수 있음
- 클래스 이름과 범위 지정자(::)으로 접근 가능
Sample s;
strcpy(s.name, "HH");
strcpy(Sample::name, "HH");
정적 멤버 함수
- 객체 없이 호출할 수 있는 멤버 ㅎ마수
- 보통 멤버함수처럼 객체이름이나 포인터로 접근 가능
- 클래스 이름과 범위 지정자(::)으로 접근 가능
- this 포인터가 없음 <- '객체' 자신을 뜻하기 때문
- 멤버 함수는 객체의 소유가 아님
Sample* s1;
s1 = &s;
s1->showName();
s1::showName();
static 멤버는 객체 이름이나 객체 포인터로 접근
- 보통 멤버처럼 접근할 수 있음
/*
객체.static 멤버
객체포인터->static 멤버
*/
- Person 타입의 객체 s와 포인터 p를 이용하여 static 멤버를 접근하는 예
Person lee;
lee.sharedMoney = 500; // 객체.static멤버 방식
Person *p;
p = &lee;
p->addShared(200); // 객체포인터->static멤버 방식
static 멤버 사용: 클래스명과 범위 지정 연산자(::)로 접근
클래스 이름과 범위 지정 연산자(::)로 접근 가능
- static 멤버는 클래스마다 오직 한 개만 생성되기 때문
// 클래스명::static 맴버
han.sharedMoney = 200; // Person::sharedMoney = 200;
lee.addShared(200); // Person::addShared(200);
- non-static 멤버는 클래스 이름을 접근 불가
Person::money = 100; // 컴파일 오류. non-static 멤버는 클래스 명으로 접근 불가
Person::addMoney(200); // 컴파일 오류. non-static 멤버는 클래스 명으로 접근 불가
static 활용
static의 주요 활용
- 전역 변수나 전역 함수를 클래스에 캡슐화
- 전역 변수나 전역 함수를 가능한 사용하지 않도록
- 전역 변수나 전역 함수를 static으로 선언하여 클래스 멤버로 선언
- 객체 사이에 공유 변수를 만들고자 할 때
- static 멤버를 선언하여 모든 객체들이 공유
static 멤버 함수는 static 멤버만 접근 가능
- static 멤버 함수가 접근할 수 있는 것
- static 멤버 함수
- static 멤버 변수
- 함수 내의 지역 변수
- static 멤버 함수는 non-static 멤버에 접근 불가
- 객체가 생성되지 않은 시점에서 static 멤버 함수가 호출될 수 있기 때문
non-static 멤버 함수는 static에 접근 가능
class Person{
public: double money;
static int sharedMoney;
// ...
int total(){ // non-static 함수는 non-static이나 static 멤버에 모두 접근 가능
return money + sharedMoney;
}
};
'공부 > C++' 카테고리의 다른 글
8. 함수와 참조, 복사생성자 (1) | 2024.05.14 |
---|---|
7. 여러가지 객체의 생성방법 (0) | 2024.05.14 |
5. 생성자와 소멸자 (0) | 2024.04.11 |
4. 클래스와 객체의 기본 (0) | 2024.04.09 |
3. 개선된 함수 기능 (0) | 2024.03.31 |