Menu
Coddy logo textTech

접근 제어자 심화

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을 나열할 것을 권장합니다.

challenge icon

챌린지

쉬움

같은 클래스의 객체들이 서로의 private 멤버에 접근할 수 있는 방식을 보여 주는 wallet 비교 시스템을 만들어 보자. 이는 C++ 접근 제어에 관한 핵심적인 통찰이다. 접근 제어는 객체 수준이 아니라 클래스 수준에서 적용된다.

코드를 구성하기 위해 두 개의 파일을 만들자:

  • Wallet.h: private 금융 데이터를 저장하면서 wallet 간 비교를 허용하는 Wallet class를 정의한다. 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 수정해야 한다.
  • 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"를 출력한다(결과가 변경되었을 수 있다).

여기서 핵심 개념은 hasMoreThan()transferTo()와 같은 메서드가 다른 Wallet 객체의 private balance 멤버에 directly access할 수 있다는 점이다. Getter가 필요하지 않다. 이는 C++의 access control이 class-based이기 때문에 가능하다. Wallet class 내부의 모든 코드는 어떤 Wallet 객체의 private 멤버에도 access할 수 있다.

<iomanip>std::fixedstd::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;
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 C++ 컴파일러