은행 예금 계좌의 예
은행의 예금 계좌에 대한 클래스를 작성한다.
예금 계좌 클래스에는 고객명, 고객의 예금 잔액, 현재 이자율 등이 있다.
고객명, 고객 예금 잔액은 별도 관리지만, 이자율은 공통이다.
공통일 경우는 보통 전역변수의 특성을 갖는다.
전역변수의 문제점
전역변수는 현재 클래스 뿐 아니라 다른 클래스에서도 접근 가능
객체 지향 철악에 위배된다.
우리가 원하는 것
전역 변수와 같은 성질의 멤버 함수이되, 외부 클래스에서는 접근할 수 없는 변수
static 변수: 지역 안에서 생성되고 프로그램 종료 시 소멸
static double dInterestRate
static으로 선언하면 클래스에 대한 객체가 생성돼도 단 하나의 변수만 메모리에 할당됨.
디자인 패턴 singleton
클래스 안에서 객체를 생성한다. 이것을 static으로 작성.
매번 객체를 생성할 때마다 메모리를 할당하는 게 아니라, 메모리 하나 를 계속 유지하게 하는 것.
static 멤버변수가 private 속성을 갖는다면 같은 클래스의 멤버함수에서만 접근 가능. 클래스 외부함수에서는 접근이 불가능.
#include<iostrem>
using namespace std;
class Deposit
{
private:
const char* strName;
double dBalance;
static double dInterestRate;
public:
Deposit(){}
Deposit(const char* name, double balance)
{
strName = name;
dBalance = balance;
}
void BankBalance()
{
dBalance = dBalance + (dBalance * dInterestRate);
}
static void SetInterestRate(double dNewRate)
{
dInterestRate = dNewRate;
}
static double GetInterestRate()
{
return dInterestRate;
}
};
double Deposit::dInterestRate = 3.3;
void main()
{
Deposit kim("김혜진", 5000);
kim.BankBalance();
Deposit lee("이댕댕", 10000);
lee.BankBalance();
cout << "변경 전 이자율 " << Deposit::GetInterestRate() << endl;
Deposit::SetInterestRate(2.5);
cout << "변경 전 이자율 " << Deposit::GetInterestRate() << endl;
}
static 멤버를 가지는 클래스의 선언 및 구조
실제 은행 예금 계좌를 나타내는 클래스와 static 멤버의 참조 구조
static 변수는 전역 변수처럼 프로그램이 시작되면서 메모리가 할당됨.
객체 생성 시만 메모리 영역이 할당되는 일반 멤버함수와는 다름.
static 멤버변수의 초기화
static 멤버변수는 전역변수와 같이 프로그램 시 한번만 초기화
static 멤버변수의 접근 지정자는 초기화 과정에서 전혀 영향을 주지 않으므로 private 속성의 static 멤버일지라도 클래스 외부에서 초기화 가능
double Deposit::dInterestRate = 0.05;
소속 클래스명 :: 영역 결정 연산자 표시해 줌으로써 초기화 할 static 멤버변수의 소속을 지정해준다. (어디에 소속되어있는 static이냐를 명시해주어야 함.)
static 초기화 코드는 헤더 파일에 작성하지 않는다. 중복을 방지하기 위해서이다.
this 포인터 사용 불가
static 멤버함수는 특정 객체에 영향을 미치지 않으므로(객체가 생기든 말든 무관하므로) this 포인터를 사용 못 함.
static 멤버함수는 static이 아닌 일반 멤버변수에 접근 불가.
static 멤버함수는 static이 아닌 일반 멤버함수 호출 불가
static 멤버함수 내에서 this 포인터를 사용하는 경우
static void SetInterestRate(double dNewRate)
{
this->dInterestRate = dNewRate;
}
this는 주소값을 갖고있기 때문에 포인터로 불리지만 본질은 객체다.
static void SetInterestRate(double dNewRate)
{
dInterestRate = dNewRate;
BankBalance();
}
일반 멤버함수인 BankBalance()는 특정 객체를 통해 호출이 되어야 하는 함수이므로 static 멤버함수 내에서는 사용 불가
const 멤버함수 안에서 일반 멤버함수를 호출할 수 없는 것과 같은 맥락.
#include<iostream>
using namespace std;
class Deposit
{
private:
const char* strName;
double dBalance;
static double dInterestRate;
static int nCount;
public:
Deposit()
{
nCount++;
cout << "객체 생성 개수 : " << nCount << endl;
}
~Deposit()
{
nCount--;
cout << "객체 소멸 개수 : " << nCount << endl;
}
Deposit(const char* name, double balance)
{
strName = name;
dBalance = balance;
}
void BankBalance()
{
dBalance = dBalance + (dBalance * dInterestRate);
}
static void SetInterestRate(double dNewRate)
{
dInterestRate = dNewRate;
}
static double GetInterestRate()
{
return dInterestRate;
}
};
double Deposit::dInterestRate = 3.3;
int Deposit::nCount= 0;
void main()
{
Deposit kim, lee;
}
출력결과
객체 생성 개수 : 1
객체 생성 개수 : 2
객체 소멸 개수 : 1
객체 소멸 개수 : 0