OOP 캡슐화 - 프렌드 (friend)
해당 객체의 멤버 함수가 아닌 함수가 private 멤버에 접근할 수 있도록
friend 라는 새로운 접근 제어 키워드를 제공
- 지정한 대상에 한해, 해당 객체의 모든 멤버에 접근할 수 있는 권한을 부여함
- 전역 함수, 클래스, 멤버 함수의 세 가지 형태로 사용 가능
- friend 키워드는 함수 원형에서만 사용해야 함 (함수 정의에서는 사용하지 않음)
- 프렌드 선언은 클래스 선언부의 public, private, protected 영역 등 어디에나 위치 가능 (위치에 따른 차이 없음)
프렌드 함수 선언
원형)
friend 클래스이름 함수이름( 매개변수목록 );
- 프렌드 함수는 클래스 선언부에 원형이 포함되지만, 클래스의 멤버 함수는 아님
- 클래스 멤버 함수가 아니지만, 멤버 함수와 같은 접근 권한을 가짐
프렌드의 필요성 : 클래스에 대해 이항 연산자를 오버로딩할 때 자주 발생
(멤버가 아닌 함수를 사용하면 해당 객체의 private 멤버에 접근할 수 없으므로)
사각형 나타내는 Rect 클래스를 정의하면서,
크기를 조절하기 위해 곱셈 연산자를 오버로딩하는 예)
class Rect{
private:
double height_;
double width_;
public:
Rect(double height, double width); // 생성자
Rect operator*(double mul) const;
friend Rect operator*(double mul, const Rect& origin); // 프렌드 함수
};
...
Rect Rect::operator*(double mul) const
{
return Rect(height_ * mul, width_ * mul);
}
Rect operator*(double mul, const Rect& origin) { return origin * mul; }
cf) 멤버 함수 원형의 맨 마지막에 const 키워드를 추가하면, 멤버 함수를 상수 멤버 함수로 정의 가능
(상수 멤버 함수 : 자신이 호출하는 객체를 수정하지 않는 읽기 전용 함수)
프렌드 클래스 : 해당 클래스의 모든 멤버 함수가 특정 클래스의 프렌드인 클래스
두 클래스가 기능상으로 서로 밀접하고, 상대의 private 멤버에 접근해야만 한다면
클래스 자체를 friend로 선언하는 게 좋음!
프렌드 클래스 선언 문법)
friend class 클래스이름;
예시)
class Rect {
private: ...
public:
...
friend class Display; // 프렌드 클래스 선언
-> Display 클래스의 모든 멤버 함수는 Rect 클래스에 대한 프렌드 접근 권한을 부여받게 됨
};
프렌드 멤버 함수 : 해당 클래스의 특정 멤버 함수만을 프렌드로 지정하는 것
(프렌드 설정이 꼭 필요한 함수에만 접근을 허락하므로, 정보 은닉과 캡슐화 개념에 더욱 가깝게 구현 가능)
class Rect {
private: ...
public:
...
friend void Display::ShowDiagonal(const Rect& target); // 프렌드 멤버 함수 선언
-> Display 클래스의 ShowDiagonal() 함수만이 Rect 클래스의 모든 멤버에 접근할 수 있음
};
cf) 전방 선언 : 순환 참조를 피하기 위해 한 클래스를 다른 클래스의 앞에 미리 선언하는 것
정적 멤버 변수/함수 (static member variable)
- 클래스에는 속하지만, 객체 별로 할당되는 게 아니라 클래스의 모든 객체가 공유하는 멤버
- 정적 멤버 변수 : 해당 클래스의 모든 객체에 대해 하나의 데이터만이 유지/관리됨
- 클래스 영역에서 선언되지만, 정의는 파일 영역에서 수행됨 -> 외부 연결을 가져서, 여러 파일에서 접근 가능
- 클래스 멤버의 접근 제한 규칙이 적용되므로, 클래스 멤버 함수나 friend만이 접근할 수 있음
-
모든 Person 객체가 공유하는 정적 멤버 변수 선언 예) class Person { private: ... public: static int person_count_; // 정적 멤버 변수 선언 ... } int Person::person_count_ = 0; // 정적 멤버 변수의 정의 및 초기화
- 정적 멤버 함수 : 해당 클래스의 객체를 생성하지 않아도, 클래스 이름만으로 호출 가능
- 객체를 생성하지 않으므로, this 포인터를 갖지 않음
- 특정 객체와 결합하지 않으므로, 정적 멤버 변수밖에 사용할 수 없음
-
문법) 1) 객체이름.멤버함수이름(); -> 일반 멤버 함수의 호출 2) 클래스이름.멤버함수이름(); -> 정적 멤버 함수의 호출 예시) class Person { private: ... public: static int person_count(); // 정적 멤버 함수의 선언 ... }; int Person::person_count() { // 정적 멤버 함수의 정의 return person_count_; }
상수 멤버 변수/함수
- 상수 멤버 변수 : 한 번 초기화하면 그 값을 변경할 수 없는 멤버 변수
- 변수의 타입 앞에 const 키워드를 사용하여 선언
- 클래스 전체적으로 사용되는 중요한 상수를 상수 멤버 변수로 정의하면 좋음
- 상수 멤버 함수 : 호출한 객체의 데이터를 변경할 수 없는 멤버 함수
- 함수 원형 끝에 const 키워드를 사용하여 선언
- 호출한 객체의 데이터를 단순 읽기만 하는 멤버 함수를 상수 멤버 함수로 정의하면 좋음
상수 멤버 변수 문법) const 타입 멤버변수이름;
상수 멤버 함수 문법) 함수원형 const;
참고)
코딩교육 티씨피스쿨
4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등
tcpschool.com
'[공부] > C++' 카테고리의 다른 글
[C++] 기본 정리 18 - OOP의 다형성(가상 함수, 추상 클래스) (1) | 2024.02.26 |
---|---|
[C++] 기본 정리 17 - OOP의 상속성(파생 클래스, 멤버 함수 오버라이딩, 다중 상속) (0) | 2024.02.26 |
[C++] 기본 정리 15 - 연산자 오버로딩 (1) | 2024.02.24 |
[C++] 기본 정리 14 - 생성자, 복사 생성자, 소멸자 (0) | 2024.02.24 |
[C++] 기본 정리 13 - 클래스, 객체 지향 프로그래밍, this 포인터 (1) | 2024.02.24 |