들어가면서
본격적으로 클래스를 공부하다보면 정적 멤버변수(static data member)를 사용하는 상황이 존재한다.
기본적으로 정적 멤버변수의 개념을 알고 있어야 클래스에서도 선언할 수 있기 때문에, 이 개념에 대해 잘 모른다면 아래 글을 참고해보자.
https://logicallaw.tistory.com/109
C++ : 정적 지역변수(static local variable)란?
들어가면서 C++ 프로그래밍을 하다보면, 전역변수 개념과 더불어 정적 지역변수라는 개념이 등장하고는 한다. 이번 글에서는 정적 지역변수의 개념을 알아보도록 한다. 정적 지역변수란? 정적
logicallaw.tistory.com
정적 멤버변수와 정적 멤버함수란?
정적 멤버변수란, 클래스 내부에서 static을 붙여서 선언된 정적 변수를 의미한다.
또한, 정적 멤버함수도 클래스 내부에서 static을 붙여서 선언된 정적 함수를 의미한다.
사전적 정의는 이 정도로 받아들이고 더 중요한 static의 특징일 것이다.
아래 전체코드와 함께 정적 멤버변수와 함수의 특징을 본격적으로 알아보도록 하자.
(아래 코드는 Circle class를 간단하게 정의하고, cnt 정적 멤버변수는 객체가 생성될 때 객체 생성 개수를 저장하는 변수이고, getCnt 정적 멤버함수는 그 카운트 개수를 출력하는 함수이다.)
#include <iostream>
using namespace std;
class Circle {
private:
int radius; //원의 반지름을 저장합니다.
static int cnt; //객체가 생성될 때마다 +1씩 증가합니다.
public:
Circle();
static int getCnt(); //객체의 개수를 리턴합니다.
};
Circle::Circle() { cnt++; }
//정적 멤버변수와 정적 멤버함수를 class 외부에서 정의합니다.
int Circle::cnt{ 0 };
int Circle::getCnt() { return cnt; }
int main(void)
{
cout << "현재 객체 생성수: " << Circle::getCnt() << endl; //0
Circle c1;
cout << "현재 객체 생성수: " << Circle::getCnt() << endl; //1
Circle c2;
cout << "현재 객체 생성수: " << Circle::getCnt() << endl; //2
return 0;
}
정적 멤버변수와 정적 멤버함수 선언하기
private:
static int cnt;
public:
static int getCnt();
정적 멤버변수와 정적 멤버함수는 클래스 내부에서 선언만 진행되는게 특징이다.
이것들의 정의는 클래스 외부에서 진행된다. 특히, 정적 멤버변수는 내부에서 정의하면 에러가 발생한다. 다만, 정적 멤버함수는 내부에서 정의가 가능은 하나, 보통은 클래스 외부에서 정의한다.
(참고로, 클래스 내부에서 선언과 동시에 초기화 가능한 정적 멤버변수가 있는데, static const int형인 변수는 바로 초기화가 가능하다. 자주 사용되지 않으니 참고사항으로 알고 넘어가자)
정적 멤버변수와 정적 멤버함수 초기화하기
int Circle::cnt{ 0 };
int Circle::getCnt() { return cnt; }
앞서 말했듯이, 두 정적 멤버변수와 정적 멤버함수는 클래스 외부에서 정의를 진행한다.
이때, 주의할 점은 앞에 static을 붙이지 않고 정의를 한다. 실수가 많은 부분이니 꼭 기억하도록 하자.
정적 멤버함수의 특징 알아보기
...
public:
static int getCnt();
};
int Circle::getCnt() { return cnt; }
정적 멤버함수에서 가장 중요한 특징이 있는데, 정적 멤버함수는 정적 멤버변수만 읽기와 쓰기가 가능하다는 점이다.
일반 멤버변수 radius를 읽기와 쓰기를 진행한다면 에러가 발생하므로 오직 정적 멤버변수를 위해 존재한다고 봐도 무관하다.
main()함수에서 정적 멤버변수의 특징 알아보기
int main(void)
{
cout << "현재 객체 생성수: " << Circle::getCnt() << endl; //0
Circle c1;
cout << "현재 객체 생성수: " << Circle::getCnt() << endl; //1
Circle c2;
cout << "현재 객체 생성수: " << Circle::getCnt() << endl; //2
return 0;
}
이번에는 main함수 코드와 출력결과까지 함께 살펴보도록 하겠다.
전체 코드를 실행하면 현재 객체수가 Circle::getCnt() 함수에 의해 출력되는데, 여기서 주목할 점이 있다.
첫 번째 출력코드는 객체 수가 0으로 출력되는데, 여기서 객체가 존재하지 않는데도 출력된다는 점이다.
정적 멤버변수는 객체가 존재하지 않더라도 무관하게 존재하는게 큰 특징이다.
이는 클래스가 정의되면서 정적 멤버변수가 초기화를 진행하기 때문에, 객체와 다른 메모리 공간을 가지고 있기 때문이다.
이러한 특징 때문에 정적 멤버변수는 모든 객체와 공유되고 어느 객체에서도 읽기와 쓰기가 가능하다.
정적 멤버함수 호출하기
Circle::getCnt()
정적 멤버함수의 호출은 보통은 클래스를 통해 호출을 하는 방식을 주로 사용한다.
객체에 의해서 c1.getCnt()와 같이 정적 멤버함수를 호출할 수 있지만, 보통은 스코프 연산자를 사용하여 Circle::getCnt()와 같이 호출을 한다.
정리: 정적 멤버변수의 특징
특징1:객체에 포함되어 있지 않고 객체와 무관하게 단독으로 존재한다.
보통 객체가 선언되면 그 안에 일반 멤버변수는 객체에 포함되어 있어서, 일반 멤버변수는 객체가 존재해야 읽거나 쓰기가 가능해진다.
하지만, 정적 멤버변수는 객체가 없어도, 클래스가 정의되어 있기만 하면 정적 멤버변수는 존재할 수가 있다. 실제로 메모리 공간에서 정적 멤버변수는 객체와 단독으로 존재한다.
특징2:객체와 무관되게 정적 멤버변수는 하나만 존재하며 모든 객체가 공유하는 변수이다.
정적 멤버변수는 객체와 무관되어서 프로그램 실행시 한 번만 초기화 하는 특성을 가지고 있다.
특징3:정적 멤버변수에 접근할 수 있는 정적 멤버함수가 필요하다.
일반적으로 정적 멤버변수의 읽기와 쓰기는 정적 멤버함수를 통해 이루어진다.
정리: 정적 멤버함수의 특징
특징1:정적 멤버변수만 접근이 가능하다.
일반 멤버변수의 읽기와 쓰기는 불가능하다.
특징2:일반 멤버함수처럼 호출이 가능하다. 하지만, 보통은 클래스를 통해 호출된다.
'C++' 카테고리의 다른 글
C++ : friend 키워드란? (0) | 2024.03.18 |
---|---|
C++ : cin >> int배열;은 왜 불가능 할까? (0) | 2024.03.15 |
C++ : 정적 지역변수(static local variable)란? (0) | 2023.12.31 |
C++ : 반복문 속 조건문의 break VS continue 차이는? (0) | 2023.12.23 |
C++ : Uniform initialization(유니폼 초기화)의 중괄호({}) 초기화 방법 (0) | 2023.12.22 |