접근 제어자 심화
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 35번째.
이제 세 가지 access 지정자를 이해했으므로, 같은 class의 여러 객체가 있을 때 이들이 어떻게 동작하는지 살펴보겠습니다. 흔히 private는 "이 객체만"을 의미한다고 생각하지만, 실제로는 "이 class만"을 의미합니다.
같은 클래스의 객체는 서로의 private 멤버에 접근할 수 있습니다:
class Person {
std::string secret;
public:
Person(std::string s) : secret(s) {}
void readSecret(const Person& other) {
// 다른 객체의 private 멤버에 접근 - 허용됨!
std::cout << other.secret;
}
};이는 접근 제어가 객체 수준이 아니라 클래스 수준에서 적용되기 때문에 작동합니다. readSecret 메서드는 Person 클래스의 일부이므로 어떤 Person 객체의 private 멤버에도 접근할 수 있습니다. 이러한 설계 덕분에 복사 생성자와 비교 연산자 같은 연산이 다른 객체의 내부 상태를 사용하여 작동할 수 있습니다.
클래스 내에서 접근 지정자 사이를 여러 번 전환할 수도 있습니다:
class Mixed {
public:
void publicMethod1();
private:
int privateData;
public:
void publicMethod2(); // 다시 public으로
private:
void privateHelper(); // 다시 private로
};이 코드는 유효한 C++이지만, 가독성을 위해 일반적으로 멤버를 access 수준별로 그룹화하는 것이 더 좋습니다. 대부분의 스타일 가이드에서는 public 멤버를 먼저 나열하고(클래스 인터페이스를 구성하므로), 그다음 protected, 마지막으로 private을 나열할 것을 권장합니다.
챌린지
쉬움같은 클래스의 객체들이 서로의 private 멤버에 접근할 수 있는 방식을 보여 주는 wallet 비교 시스템을 만들어 보자. 이는 C++ 접근 제어에 관한 핵심적인 통찰이다. 접근 제어는 객체 수준이 아니라 클래스 수준에서 적용된다.
코드를 구성하기 위해 두 개의 파일을 만들자:
Wallet.h: private 금융 데이터를 저장하면서 wallet 간 비교를 허용하는Walletclass를 정의한다. class에는 다음이 있어야 한다:- Private 멤버:
ownerName(문자열) 및balance(실수) - owner name과 initial balance를 받는 Constructor
- owner의 이름을 반환하는 public Getter
getOwnerName() - 이 wallet의 balance를 다른 wallet의 private balance와 비교하여, 이 wallet이 더 많은 금액을 가지고 있으면
true를 반환하는 메서드hasMoreThan(const Wallet& other) - 두 wallet의 private balance 합계를 반환하는 메서드
combinedBalance(const Wallet& other) - 이 wallet에서 다른 wallet으로 금액을 이동하는 메서드
transferTo(Wallet& other, double amount). amount가 양수이고 이 wallet의 balance를 exceed하지 않는 경우에만 두 wallet의 private balance를 directly 수정해야 한다.
- Private 멤버:
main.cpp: 객체 간 private 멤버 access를 보여 준다. input에서 두 owner name과 두 balance를 읽는다(네 줄: name1, balance1, name2, balance2). 그런 다음:- input 값으로 두 개의
Wallet객체를 Create한다. combinedBalance()를 사용하여"Combined wealth: $<amount>"를 출력한다.- wallet을 Compare하고 balance가 더 높은 owner에 대해
"<name> has more money"를 출력한다(이를 determine하기 위해hasMoreThan()사용). transferTo()를 사용하여 first wallet에서 second wallet으로100.0을 이동한다."After transfer:"를 출력한다."Combined wealth: $<amount>"를 again 출력한다(변경되지 않아야 한다).- again Compare하고
"<name> has more money"를 출력한다(결과가 변경되었을 수 있다).
- input 값으로 두 개의
여기서 핵심 개념은 hasMoreThan() 및 transferTo()와 같은 메서드가 다른 Wallet 객체의 private balance 멤버에 directly access할 수 있다는 점이다. Getter가 필요하지 않다. 이는 C++의 access control이 class-based이기 때문에 가능하다. Wallet class 내부의 모든 코드는 어떤 Wallet 객체의 private 멤버에도 access할 수 있다.
<iomanip>의 std::fixed 및 std::setprecision(2)를 사용하여 모든 monetary value를 소수점 이하 두 자리로 Format한다. balance input은 std::stod()를 사용하여 변환한다.
직접 해보기
#include <iostream>
#include <string>
#include <iomanip>
#include "Wallet.h"
using namespace std;
int main() {
// 입력 읽기: name1, balance1, name2, balance2
string name1, name2;
string balanceStr1, balanceStr2;
getline(cin, name1);
getline(cin, balanceStr1);
getline(cin, name2);
getline(cin, balanceStr2);
double balance1 = stod(balanceStr1);
double balance2 = stod(balanceStr2);
// 화폐 값에 대한 출력 형식 설정
cout << fixed << setprecision(2);
// TODO: 입력 값으로 두 개의 Wallet 객체 생성
// TODO: Print combined wealth using combinedBalance()
// Format: "Combined wealth: $<amount>"
// TODO: Compare wallets using hasMoreThan() and print who has more money
// Format: "<name> has more money"
// TODO: transferTo()를 사용하여 첫 번째 지갑에서 두 번째 지갑으로 100.0 이체
// TODO: Print "After transfer:"
// TODO: Print combined wealth again
// TODO: Compare again and print who has more money
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C++ 컴파일러