인스턴스 vs 정적 멤버
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 104개 중 27번째.
지금까지 만든 모든 멤버 변수는 특정 객체에 속합니다. Player 객체를 두 개 만들면 각각 고유한 name과 health를 가집니다. 이를 인스턴스 멤버라고 합니다. 즉, 클래스의 각 인스턴스마다 별도로 존재합니다.
하지만 모든 객체에서 공유되는 데이터가 필요하다면 어떻게 해야 할까요? 예를 들어, 전체적으로 플레이어가 몇 명 존재하는지 추적하는 경우입니다.
여기서 정적 멤버가 등장합니다. 정적 멤버는 특정 객체가 아니라 클래스 자체에 속합니다.
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 |
정적 멤버는 카운터, 구성 값 또는 개별 객체가 아니라 논리적으로 클래스에 속하는 모든 데이터에 유용합니다.
챌린지
쉬움인스턴스 멤버와 static 멤버를 사용하여 개별 제품 세부 정보와 전체 재고 통계를 모두 추적하는 제품 재고 시스템을 만들어 봅시다.
코드를 구성하기 위해 두 개의 파일을 만들게 됩니다:
Product.h: 개별 제품을 관리하면서 재고 전체 데이터를 추적하는Productclass를 Define합니다. class에는 다음이 있어야 합니다:- 인스턴스 멤버:
name(문자열) 및price(double): 각 제품에 고유함 - 현재 존재하는 제품 수를 세는 static 멤버
totalProducts - 모든 제품의 합산 가격을 추적하는 static 멤버
totalValue - name과 price를 인수로 받고, 인스턴스 멤버를 초기화하며, 두 static 카운터를 업데이트하는 생성자 (카운트를 Increment하고, 전체 값에 price를 더함)
- 제품이 제거될 때 static 카운터를 업데이트하는 소멸자 (카운트를 Decrement하고, 전체 값에서 price를 뺌)
getInfo()메서드: 다음 format의 문자열을 반환함:"<name>: $<price>"- 문자열을 반환하는 static 메서드
getInventoryStats():"Products: <count>, Total Value: $<value>"
- 인스턴스 멤버:
main.cpp: 인스턴스 멤버는 고유하게 유지되는 반면 static 멤버는 모든 객체 간에 공유되는 방식을 보여 줍니다. 입력에서 두 제품의 이름과 가격을 읽습니다 (name1, price1, name2, price2: 각각 별도의 줄에 입력). 그런 다음:- class 이름을 사용하여 초기 재고 통계를 출력합니다:
Product::getInventoryStats() - 중괄호를 사용하여 scope block을 만들고, 그 안에서 첫 번째 name과 price로
Product를 Create합니다. 해당 제품의 정보와 current 재고 통계를 출력합니다. - block이 끝난 후 (첫 번째 제품이 destroyed된 후),
"After first scope:"를 출력하고 이어서 재고 통계를 출력합니다. - 두 번째 name과 price로 another
Product를 Create합니다. 해당 제품의 정보와 재고 통계를 출력합니다. - name이
"Bonus"이고 price가5.00인 세 번째Product를 Create합니다. 최종 재고 통계를 출력합니다.
- class 이름을 사용하여 초기 재고 통계를 출력합니다:
header 파일에서 class 외부에 (class 정의 후) static 멤버를 Define해야 한다는 점을 기억하세요. <iomanip>의 std::fixed와 std::setprecision(2)를 사용하여 price를 소수점 이하 두 자리로 format하세요.
#include "Product.h"를 사용하여 main.cpp에 header 파일을 include하세요.
직접 해보기
#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 the block ends, print "After first scope:"
// 그런 다음 재고 통계 출력
// TODO: name2와 price2로 또 다른 Product 생성
// 정보와 재고 통계 출력
// TODO: 이름이 "Bonus"이고 가격이 5.00인 세 번째 Product 생성
// 최종 재고 통계 출력
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 C++ 컴파일러