일반 멤버들은 객체가 생성될 때 메모리가 잡힘. -> 객체 없이는 멤버에 접근할 수 없었음.
static 멤버는 class가 읽히는 순간 메모리가 잡힌다.
일반 메모리에 접근할 수 있다는 보장이 없기 때문에 일반 멤버에 접근할 수 없다. static 멤버에만 접근 가능
일반 메소드에서 스태틱 메모리에는 항상 접근 가능, 스태틱메소드는 일반 메모리에 항상 접근할 수는 없다.
static이라는 말을 붙이지 않으면 int getPopulation() 함수는 객체로만 접근 가능하다
ex) p::getPopulation() o , Person::getPopulation() x
그러니 Person::getPopulation()을 쓰고 싶다면 static int getPopulation() 으로 정의해야한다.
static 변수들은 클래스 외부에서 초기화해주어야 한다.
코드전문
#include <iostream>
#include <vector>
class Snack {
protected:
static int population;
public:
Snack() {
population++;
}
static int get_population() {
return population;
}
virtual std::string get_info() {
return "";
}
};
class Choco : public Snack {
static int population;
std::string shape;
public:
Choco(std::string shape) {
this->shape = shape;
}
static int get_population() {
return population;
}
std::string get_info() {
return shape + "모양 초콜릿";
}
};
class Candy : public Snack{
static int population;
std::string flavor;
public:
Candy(std::string flavor) {
population++;
this->flavor = flavor;
}
static int get_population() {
return population;
}
std::string get_info() {
return flavor + "맛 사탕";
}
};
int Snack::population = 0;
int Choco::population = 0;
int Candy::population = 0;
int main()
{
std::vector<Snack*> snackbasket = {};
int num = 0;
while (1) {
int answer;
std::cout << "과자 바구니에 추가할 간식을 고르시오 (1: 사탕, 2: 초콜릿, 0: 종료) : ";
std::cin >> answer;
if (answer == 1) {
std::string name;
std::cin >> name;
snackbasket.push_back( new Candy(name));
}
else if (answer == 2) {
std::string name;
std::cin >> name;
snackbasket.push_back(new Choco(name));
}
else if (answer == 0) {
break;
}
else {
std::cout << "0~2 사이의 정수를 입력하세요." << std::endl;
}
}
std::cout << Snack::get_population() <<"개 담겼습니다 :" << std::endl;
for (int i = 0; i < Snack::get_population(); i++) {
std::cout << snackbasket[i]->get_info() << std::endl;
}
}
Snack 클래스로 정의된 벡터에 Snack의 자식 클래스인 Choco, Candy클래스의 값을 업캐스팅을 활용해 벡터에 넣는다.
int main()
{
std::vector<Snack*> snackbasket = {};
int num = 0;
while (1) {
int answer;
std::cout << "과자 바구니에 추가할 간식을 고르시오 (1: 사탕, 2: 초콜릿, 0: 종료) : ";
std::cin >> answer;
if (answer == 1) {
std::string name;
std::cin >> name;
snackbasket.push_back( new Candy(name));
}
else if (answer == 2) {
std::string name;
std::cin >> name;
snackbasket.push_back(new Choco(name));
}
else if (answer == 0) {
break;
}
else {
std::cout << "0~2 사이의 정수를 입력하세요." << std::endl;
}
}
std::cout << Snack::get_population() <<"개 담겼습니다 :" << std::endl;
for (int i = 0; i < Snack::get_population(); i++) {
std::cout << snackbasket[i]->get_info() << std::endl;
}
}
여러 클래스가 혼재된 인스턴스들에 대해
for (int i = 0; i < Snack::get_population(); i++) {
std::cout << snackbasket[i]->get_info() << std::endl;
}
각각의 클래스에서 오버라이딩 된 get_info()를 작동시켰을 때,
class Snack {
protected:
static int population;
public:
Snack() {
population++;
}
static int get_population() {
return population;
}
virtual std::string get_info() {
return "";
}
};
class Choco : public Snack {
static int population;
std::string shape;
public:
Choco(std::string shape) {
this->shape = shape;
}
static int get_population() {
return population;
}
std::string get_info() {
return shape + "모양 초콜릿";
}
};
class Candy : public Snack{
static int population;
std::string flavor;
public:
Candy(std::string flavor) {
population++;
this->flavor = flavor;
}
static int get_population() {
return population;
}
std::string get_info() {
return flavor + "맛 사탕";
}
};
같은 이름의 함수지만 서로 다른 역할을 하는 다형성을 보인다.