Menu
Coddy logo textTech

인스턴스 vs 정적 멤버

Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 104개 중 27번째.

지금까지 여러분이 생성한 모든 멤버 변수는 특정 객체에 속해 있습니다. 두 개의 Player 객체를 생성하면, 각 객체는 자신만의 namehealth를 가집니다. 이것들을 인스턴스 멤버라고 부르며, 클래스의 각 인스턴스마다 별도로 존재합니다.

하지만 모든 객체에서 공유되는 데이터가 필요하다면 어떻게 해야 할까요? 예를 들어, 전체 플레이어 수가 몇 명인지 추적하는 경우입니다.

이것이 정적 멤버(static members)가 등장하는 이유입니다. 정적 멤버는 특정 객체가 아니라 클래스 자체에 속합니다.

class Player {
    std::string name;           // 인스턴스 멤버 - 각 플레이어는 자신만의 이름을 가집니다
    int health;                 // 인스턴스 멤버
    
    static int playerCount;     // 정적 멤버 - 모든 플레이어가 공유합니다
    
public:
    Player(std::string n) : name(n), health(100) {
        playerCount++;          // 플레이어가 생성될 때마다 증가합니다
    }
    
    ~Player() {
        playerCount--;          // 플레이어가 소멸될 때마다 감소합니다
    }
};

주요 차이점: 인스턴스 멤버는 객체를 통해 접근하는 반면, 정적 멤버는 클래스 이름 자체를 통해 접근할 수 있습니다. 인스턴스 멤버는 "객체당 하나", 정적 멤버는 "클래스당 하나"라고 생각하면 됩니다.

인스턴스 멤버정적 멤버
각 객체마다 고유함모든 객체 간에 공유됨
객체가 생성될 때 생성됨객체가 생성되기 전부터 존재함
객체를 통해 접근: player.health클래스를 통해 접근: Player::playerCount

정적 멤버는 카운터, 설정 값 또는 개별 객체보다는 논리적으로 클래스에 속하는 모든 데이터에 유용합니다.

challenge icon

챌린지

쉬움

인스턴스 멤버와 정적(static) 멤버를 사용하여 개별 제품의 상세 정보와 전체 재고 통계를 추적하는 제품 재고 시스템을 구축해 보겠습니다.

코드를 정리하기 위해 두 개의 파일을 생성합니다:

  • Product.h: 개별 제품을 관리하면서 재고 전체 데이터를 추적하는 Product 클래스를 정의합니다. 클래스에는 다음이 포함되어야 합니다:
    • 인스턴스 멤버: name (string) 및 price (double) — 각 제품마다 고유함
    • 정적 멤버 totalProducts: 현재 존재하는 제품의 총 개수를 카운트함
    • 정적 멤버 totalValue: 모든 제품의 합산 가격을 추적함
    • 생성자: 이름과 가격을 인자로 받아 인스턴스 멤버를 초기화하고, 두 정적 카운터를 업데이트함 (개수 증가, 총 가치에 가격 추가)
    • 소멸자: 제품이 제거될 때 정적 카운터를 업데이트함 (개수 감소, 총 가치에서 가격 차감)
    • getInfo() 메서드: "<name>: "<name>: $<price>"lt;price>" 형식의 문자열을 반환함
    • 정적 메서드 getInventoryStats(): "Products: <count>, Total Value: "Products: <count>, Total Value: $<value>"lt;value>" 형식의 문자열을 반환함
  • main.cpp: 인스턴스 멤버가 고유하게 유지되는 동안 정적 멤버가 모든 객체에서 어떻게 공유되는지 보여줍니다. 입력으로부터 두 개의 제품 이름과 가격(name1, price1, name2, price2 — 각각 별도의 줄에 입력됨)을 읽은 후 다음을 수행합니다:
    • 클래스 이름을 사용하여 초기 재고 통계를 출력합니다: Product::getInventoryStats()
    • 중괄호를 사용하여 스코프 블록을 만들고, 그 안에서 첫 번째 이름과 가격으로 Product를 생성합니다. 해당 제품의 정보와 현재 재고 통계를 출력합니다.
    • 블록이 끝난 후(첫 번째 제품이 소멸됨), "After first scope:"를 출력하고 이어서 재고 통계를 출력합니다.
    • 두 번째 이름과 가격으로 또 다른 Product를 생성합니다. 해당 제품의 정보와 재고 통계를 출력합니다.
    • 이름이 "Bonus"이고 가격이 5.00인 세 번째 Product를 생성합니다. 최종 재고 통계를 출력합니다.

정적 멤버는 헤더 파일의 클래스 정의 외부(클래스 정의 뒤)에서 정의해야 함을 기억하세요. 가격은 <iomanip>std::fixedstd::setprecision(2)를 사용하여 소수점 둘째 자리까지 형식을 맞춥니다.

main.cpp에 #include "Product.h"를 사용하여 헤더 파일을 포함시키세요.

치트 시트

C++는 두 가지 유형의 클래스 멤버를 지원합니다: 인스턴스 멤버정적 멤버.

인스턴스 멤버는 각 객체마다 고유합니다 - 모든 인스턴스는 자신만의 복사본을 가집니다:

class Player {
    std::string name;  // 각 플레이어는 자신만의 이름을 가집니다
    int health;        // 각 플레이어는 자신만의 체력을 가집니다
};

정적 멤버는 클래스의 모든 객체 간에 공유됩니다 - 클래스 자체에 속하는 단 하나의 복사본만 존재합니다:

class Player {
    static int playerCount;  // 모든 플레이어에 의해 공유됨
    
public:
    Player(std::string n) : name(n), health(100) {
        playerCount++;  // 공유 카운터 증가
    }
    
    ~Player() {
        playerCount--;  // 파괴될 때 감소
    }
};

주요 차이점:

인스턴스 멤버정적 멤버
각 객체마다 고유함모든 객체 간에 공유됨
객체가 생성될 때 생성됨객체가 생성되기 전부터 존재함
객체를 통해 접근: player.health클래스를 통해 접근: Player::playerCount

정적 메서드는 클래스 이름을 사용하여 호출할 수 있으며 정적 멤버에만 접근할 수 있습니다:

class Player {
    static int playerCount;
    
public:
    static int getPlayerCount() {
        return playerCount;  // 정적 멤버에만 접근 가능
    }
};

// 클래스 이름을 사용하여 호출
int count = Player::getPlayerCount();

정적 멤버는 클래스 외부에서 정의되어야 합니다 (일반적으로 .cpp 파일이나 헤더의 클래스 정의 뒤에서):

int Player::playerCount = 0;

정적 멤버는 카운터, 공유 설정 값 또는 개별 객체보다는 논리적으로 클래스에 속하는 모든 데이터에 유용합니다.

직접 해보기

#include <iostream>
#include <string>
#include "Product.h"

using namespace std;

int main() {
    // 입력 읽기
    string name1;
    double price1;
    string name2;
    double price2;
    
    getline(cin, name1);
    cin >> price1;
    cin.ignore();
    getline(cin, name2);
    cin >> price2;
    
    // TODO: Product::getInventoryStats()를 사용하여 초기 재고 통계 출력
    
    // TODO: 중괄호를 사용하여 스코프 블록 생성
    // 블록 내부:
    //   - name1과 price1으로 Product 생성
    //   - getInfo()를 사용하여 정보 출력
    //   - 현재 재고 통계 출력
    
    // TODO: 블록이 끝난 후, "After first scope:" 출력
    // 그 다음 재고 통계 출력
    
    // TODO: name2와 price2로 또 다른 Product 생성
    // 해당 정보와 재고 통계 출력
    
    // TODO: 이름이 "Bonus"이고 가격이 5.00인 세 번째 Product 생성
    // 최종 재고 통계 출력
    
    return 0;
}
quiz icon실력 점검

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

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