: 멤버 데이터 내의 static 변수는 클래스내에 오로지 한개만 할당되어 있어야 하므로, 외부파일인 cpp에서 할당 즉 초기화를 해놓아야 한다.
여러개의 객체들이 공통의 static 변수를 참고하려면 클래스 헤더에서 정의하는 것이 아니라, 외부 공간에서 한번만 할당한 친구를 찾아야 하지 않을까?
클래스 내에서 안되는 이유는?
: 참고 사이트
https://ansohxxn.github.io/cpp/chapter8-10/
내 생각
: 전문가 c++에서 멤버 데이터 초기화부분을 공부하면서 Object 클래스 를 보면, 멤버데이터 data가 1로 초기화되는 영역도 생성자의 선처리 영역으로 진입한 후에 초기화가 이루어졌고, 객체마다 data 멤버데이터가 생성되었다.
그렇다면 객체마다 생성되는 것이 아니라 클래스에 단 한번만 할당되는 static의 경우
선언부에서 정의를 하면 안된다는 것을 도출할 수 있따.
: 전문가 c++
static 멤버 변수를 선언하면, 해당 변수는 객체에 속한 것이아니다.
클래스에 속한 것이고, 반드시 공간을 할당하는 코드를 cpp파일에다 작성해야 한다. 그러지 않으면 링크에러가 발생한다.
-> 초기화는 cpp 파일에서 해야 한다. 컴파일시에 훑고 지나간다.
일단 뜬금포지만, extern 과 static 차이가 있따.
extern은 외부 전역이고 ,static 은 내부 전역이다.
링크에러가 왜 발생할까? 왜 외부에 할당해야 할까? 에 대한 내 생각.
static 멤버변수가 있는 클래스의 경우, 객체화를 할 경우, 외부에서 할당하지 않으면 오류 발생한다.
첫번째로는 컴파일을 하게 되면, static 멤버를 프로그램 시작하자마자 생명이 부여되고, 프로그램이 종료될때 소멸한다. (클래스가 한번이라도 생성되지 않아도 반드시 어느 공간에 할당이 되어 있어야 한다. )
그렇다는 것은 객체화가 되는 순간 할당되는 것이 아니라는 것이므로,
클래스의 입장에서는 외부 공간인 cpp에다가 따로 할당을 해야 한다.
main에서 static 멤버에 대해 get , set하지 않으면 문제가 되지 않음.
그런데 get 하는 순간 문제 발생한다.
: 링크에러 발생한다.
-> get하려는 순간 static 공간에 할당되어야 하는 c가 도대체 어디다가
메모리를 할당한거야??? 없는데??? 그래서 링크에러가 발생한 거다.
외부 공간에다가 할당하면 문제가 되지 않는데. 일단 할당이랑 초기화 하는 부분에 대해 알아보자.
: 이러한 에러가 발생했다.
-> 맨 위부분에 할당과 선언부를 구분해야 한다는 내용이 있다.
위의 문제를 해결하는 방법은 const 나 constexpr을 붙이는 방법도 있는데.
이러한 문제가 발생한 근복적인 이유는 할당을 하지 않아서이다.
const 나 constexpr를 붙이지 않는다면, 클래스 헤더 내에서 초기화는 불가하다.
-> 계속 말했는데, static 멤버변수는 객체를 초기화하는 순간이 아니라,
프로그램이 시작되는 순간에 할당되는 것이기에 외부에 할당해야 한다.
멤버 이므로 접근 지정자 사용가능함.
그러나 메모리 영역은, 객체에 위치하는 것이 아닌 static 영역에 올라와져 있음.
-> Problem: 확인하기 위해서 sizeof 로 객체의 크기를 확인하라.
: 객체의 메모리에 static이 있다면, 8이 출력되어야 함.
반드시 cpp 외부에서 정의를 해야함.
: 정의를 하지 않아서 링크 에러 발생하는 것을 확인할 수 있다.
-> 왜 외부에서 할당을 해야하는 이유가 중요하다. 그리고 그 이유를 알아야만 내가 자알 사용할 수 있다.
모든 객체가 공유함.
헤더와 cpp로 분류할 때, 정의는 cpp에서 정의해야 하는 것이 보통이다.
-> 위의 링크에러 해결함.
: 프로그램 시작시 static 변수 생성됨.
: 클래스 이름:: 을 이용해 접근하는 것이 가독성에 좋음.
구별을 할 수 있음.
static 아닌 멤버 데이터는 객체(점). 을 사용 obj.data;
static은 obj.data / OBJ::data 2개 모두 다 사용이 가능함.
but, Obj::data로 접근하자!
: 위의 내용을 코드해서 확인하라.
1) obj.func();
2) OBJ::func();
메모리의 어디에 있을까?
- 정적 멤버 함수는 소속은 객체이지만, 메모리는 static에 있음.
- 멤버 데이터와 함수의 메모리는 각 객체의 메모리에 있음.
1) 정적 멤버 함수에서 멤버의 데이터 함수 접근 불가능함.
-> 메모리에 놓여진 공간이 다르기 때문임.
2) 멤버 함수에서는 정적 멤버 함수를 호출할 수 있음.
-> 멤버 데이터와 정적 멤버 데이터의 소속은 모두 해당 클래스에 있음.
class Car
{
private :
static int cnt;
int data;
public :
static void foo()
{
cnt++; // 가능
data++ // 불가함.
goo() // 불가함.
}
void goo()
{
cnt ++ // 가능
data++; // 가능.
foo() // 가능!
}
}
: Car 클래스를 만들어라, 객체의 갯수를 세는 static cnt 와
각 객체의 speed , static foo 함수, void goo 함수를 만들고,
foo 에서 2개의 멤버 접근 하라.
goo에서도 2개의 멤버 에 접근해보아라.