차이점?
종이 한장 차이이다.
구조체는 "기본 접근 지정가"가 public, 클래스는 기본 상태가 private이다.
이거말고는 거의 다 똑같다.
왜?
=> C++이 C에서 발전하다 보니까 어느정도의 호환성을 맞추기 위해서... 이렇게됨.
static = 정적 = 고정된.
클래스 내부에 멤버 변수로 static int _attack을 넣어주면
이게 사실상 "설계도 상으로만 존재"하는 것이다.
아예 이렇게 밖으로 빠져있는 느낌으로 보면된다.
이렇게 일단 "전역 선언?" == "외부 선언"
일반 멤버 변수 : 특정 마린 객체에 종속적
정적 멤버 변수 : 특정 마린 객체에 종속적이지 않고 마린이라는 "클래스"자체와 연관있다.
(C#도 똑같이 동작한다)
이런 static Test함수가 있을 때 이녀석은 Marine이라는 클래스와 연관성이 있다.
그런데 _hp를 건드릴려고하면 에러가 나는데
어떤 객체의 _hp 를 건드려야 할지를 모르기 때문에 이런문제가 발생한다.
(static 함수에서는 static 변수만 사용할 수 있다고 들었다)
그래서 일반 멤버 변수를 수정할 수는 없고
static함수안에서는 static변수를 고치는 것은 가능함.
Marine이라는 객체를 만들어서 메모리를 보면은
s_attack이라는 변수는 메모리에 안 잡히는데
한번 까보도록 하자.
s_attack 이라는 녀석은 저멀리 어딘가에 딱 하나만 만들어서
공용으로사용하는 느낌이라고 보면된다.
=> 데이터 영역에 올라가는데
초기화 하면 .data에 올라가고
초가화 하지 않으면 .bss영역에 올라간다.
이런식으로 main함수 내에 선언및 초기화를 해주더라도
static 변수는 .data에 올라가고
int a는 스택에 올라간다.
class Player
{
public:
int m_iId;
}
int GenerateId()
{
// 정적 지역 객체
static int s_id = 1;
}
이거 보고 딱 드는 생각이 느낌적으로 오? 라는 느낌을 받음
뭔가 보안성이 좋아보이는 느낌
이것을
"생명 주기", "가시 범위" 관점에서 보도록 하자.
일반적으로 스택에 올라가는 변수들은 함수가 시작할 때
함수 start -> 스택메모리에 스택프레임 잡히고
-> 함수 종료 -> 사라짐.
이런 생명 주기를 가지는데
"정적 지역 객체"의 생명주기는 "프로그램 시작 ~> 프로그램 종료"
(메모리에 항상 올라가있다. => 데이터 영역에 (.data) )
를 따라간다.
이 정적 지역 객체인
static int s_id = 1;를 사용할 수 있는 범위는
GenerateId라는 함수 안에서만 사용할 수 있는 것이다.
static변수는 처음에 딱 한번만 초기화 하고 초기화 하지 않는다.
이 함수 여러번 호출해도 static 정적 지역 객체는 딱 한번만 초기화를 한다.
클래스 내부의 static은
class자체와 연관이 있다.
클래스에 붙어있는 녀석이다.
특정 객체에 종속적이지 않기 때문에
함수내부에 static 변수가 있을 경우에는
"접근"은 그 함수를 통해서만 할 수 있고
클래스 내부에 선언되어 있을 경우 클래스의 객체를 통해서만 접근이 가능하다.
이렇게 하면 안되고
이렇게 해줘야하는데
이유가 뭐냐하면은 "클래스 객체에 종속적이지 않기 때문에"
정적변수는 초기화를 한번만 하는데
클래스 내부에서 초기화를 해주게 되면은
객체를 만들 때 마다 static int m_iAttack = 10;으로 설정할 것인가?
말도 안된다.
그래서 명시적으로 밖에다가 초기화를 한번 해주는 것이다.