-
[C++] staticC++ 2023. 4. 6. 20:54
c++에서의 static 은 원래의 global 전역변수를 클래스로 끌어들이는 역할이다

C에서 쓰인 global 전역변수가 C++에서는 static으로 업그레이드 된 것이다
참고로 C++에 static 클래스라는 것은 없다
static 변수와 static 함수 즉, static 멤버만 존재한다
또한 static 도 접근지정자를 탄다
public private 을 잘 구별해서 써줘야한다
[global이 쓰레기인 이유]
global 전역변수 는 코드 전체에서 전역적으로 쓰이는데
1. 어떤 변수,함수와 연관되어 있고 어디 소속인지 파악하기 힘들다
코드 상에 왜 있는지 파악하기도 어렵
2. 아무 곳에서 접근 가능하기 때문에 보안성이 매우 떨어진다
(public으로 해놓으면 모든 곳에서 접근 가능하기 때문)
따라서 C++에서는 "특정 클래스의 전역변수임" 을 표시하기 위해 static이란 키워드를 만들었다
C++ 클래스 내 static 변수 선언의 의미는
밖에 찾으면 이 변수 있어 그리고 그건 내꺼야 이런 의미다
global 변수는 쓰레기 선언. static 써라
교수말 ㅇㅇ
[static 멤버 특징]
1. lifetime (생명주기)
1) 프로그램과 생명을 같이함
프로그램 시작 시 생성, 종료시 소멸
2) 컴파일 시 메모리에 할당됨 ( main 시작 전에 이미 생성되어있음 )
이때 static 멤버는 평생쓸거(프로그램 돌아가는 동안)
클래스 당 딱 한개 만 생성됨
3) 객체가 생기기 전에 생성되어있음
4) 객체가 사라져도 여전히 존재
이 static의 lifetime 때문에 할 수 없는게 non-static 멤버에 접근 불가인 것
왜냐하면 static 변수는 항상 무조건 non-static 멤버들보다는 먼저 생성되어있기때문에
non-static 멤버들을 사용할 시, non-static 멤버들은 생성되지 않은 상황일 수 도 있기 때문!
2. scope
멤버는 클래스 당 하나 생성
멤버는 객체 내부가 아닌 별도의 공간에 생성
3. 공유가능여부
동일한 클래스 객체들에 의해 공유됨
여러 객체들이 하나의 static 변수를 공유
[STATIC 사용 방법]
class Person { public: double money; void addMoney(int money) { this->money = money; } static int sharedMoney; static void addShared(int n) { sharedMoney += n; } };1. 범위지정연산자(::)
int Person::sharedMoney = 10;static 클래스 멤버변수는 외부선언이 필수임
( 클래스 내에서 초기화할 수 없기 때문)
예외 : const static / const 붙어있으므로 선언과 동시에 초기화해줘야함!
외부선언 안하면 링크 오류 남!
2. 객체나 포인터로 직접 참조
static 멤버여도 보통 멤버참조할때처럼 . 으로 참조하면 된다
Person lee; lee.sharedMoney = 500; Person* p = &lee; p->sharedMoney = 500;2번 보다 1번이 너 나은게
2번은 형식상 static 변수를 참조하고 있다는 느낌보다 개별 멤버변수를 참조하고 있다는 느낌이 강하다
따라서 코드 상 static 느낌을 풍기는 1번을 쓰는게 좋다.
static 참조인걸 쉽게 캐치할 수 있기 때문이다.
(non-static 변수들은 클래스이름으로 참조 불가능하기 때문)
[static 언제씀]
앞서 얘기했듯이
1. 전역변수나 전역함수를 클래스에 캡슐화
전역변수나 전역함수를 특정 클래스 외에서는 가능한 사용하지 않도록,
static으로 선언하여 클래스 멤버로 넣는 것이다
2. 객체 사이에 공유 변수를 만들고자 할때
static 멤버를 선언하여 모든 객체들이 공유
[static 함수]
class MyMath { public: static const double PI; static int add(int a, int b) { return a + b; } static int multiply(int a, int b) { return a * b; } static double circleArea(double r) { return PI * r * r; } }; const double MyMath::PI = 3.141592;함수만 있는 클래스에 static을 써주면 매우 유용하다
(보통 다 이렇게 한다)
만약 static 선언을 안하면, 함수를 쓰기 위해 불필요하게 객체를 생성해야한다 (생성자 호출해서)
멤버변수를 초기화해야할 일도 없는데 말이다!!
클래스 내 함수들을 static으로 선언하면 이런 불필요한 객체생성을 막을 수 있다.
해당 클래스 내 모든 함수들을 static으로 만든다
이러면 객체 생성을 하지 않고 그저 (class::)범위지정연산자로 사용가능하다
예를 들어 multiply 함수를 사용하고 싶으면
Math::multiply(5,6);보통 wrapper 클래스가 이와 같다.
[클래스 내 static 변수 vs 함수 내 static 변수]
클래스 내 static 변수는 해당 클래스 밖에서 범위지정연산자:: 를 활용하여 초기화한다
class MyMath { public: static double PI; // static 변수 static int add(int a, int b) { return a + b; } static int multiply(int a, int b) { return a * b; } static float circleArea(double r) { return PI * r * r; } }; double MyMath::PI = 3.141592; // static 밖에서 초기화함수 내에서 쓰이는 static함수는 해당 함수 안에서 초기화 한다
// 함수 속에서 사용하는 static 변수 void func() { static int fcount = 0; // func() 함수에서만 쓰이는 변수를 함수 내부로 끌어들일 수도 있음 // 밖에 있던 전역변수를 끌어옴 // 0 들어가는건 한번만 실행됨 // 프로그램 시작과 동시에 메모리 할당 // 함수 안에서 값 초기화 if (fcount == 0) { cout << "Your first call" << endl; } else { cout << "You already called me!" << endl; } fcount++; }'C++' 카테고리의 다른 글
[C++] 접근지정자 (access modifiers) (3) 2023.04.11 [C++] friend (2) 2023.04.11 [C++] inline function (0) 2023.04.03 [C++] 소멸자 (0) 2023.03.25 [C++] Iterator(반복자) (1) 2023.02.20