#28. static, this, extern, 복사생성자
#11. 지역변수, 전역변수 및 메모리구조 (2) (tistory.com)
#11. 지역변수, 전역변수 및 메모리구조 (2)
# 지역변수, 전역변수 #10. 함수 및 메모리 구조 (tistory.com) 재사용성이 좋기 때문에 자주 사용한다. 함수는 1. input O output O ex) y=f(x) 2. input O output X ex) srand(seed) 3. input X output O ex) ra..
hyukee.tistory.com
#static
static은 기존에 Data영역에 저장되며,
지역변수의 해당 지역내에서만 접근이 가능의 특성
전역변수의 Data영역에 저장되어 함수가 끝나도 값이 버려지지 않는다는 특성
두가지 특성을 모두 가지고 있다고 했다.
그 static 특성을 class에서 사용시 그대로 가지고 있다.
class 멤버 변수로 static 을 가지게 되면, 그 static 멤버 변수의 초기화는 전역에서 되어야 한다.
이때 전역에서 초기화 할때에는 자료형 클래스명::멤버변수명 = 초기화값; 으로 진행 한다.
또한 static 변수는 해당 클래스로 만든 객체끼리 값을 모두 공유한다.
#include "stdafx.h"
class CLS
{
static int iA;
public:
void iAplus()
{
++iA;
cout << "iA: " << iA << endl;
}
};
int CLS::iA = 0; // static변수 초기화
void main()
{
CLS cls;
cls.iAplus();
cls.iAplus();
cls.iAplus();
CLS cls2;
cls2.iAplus();
}
-> CLS클래스의 cls2 객체가 1이 아닌 4로 나왔다.
또한 static은 프로그램 실행 시 메모리에 등록이 된다.
따라서 객체 생성이 될 때 메모리에 등록이 되는 일반변수와는 메모리에 등록되는 시점이 다르다
-> static 멤버함수에 일반멤버변수나 일반멤버함수는 쓸 수 없다.
static은 객체생성을 하지 않아도 프로그램 실행시 메모리에 등록 된다
#include "stdafx.h"
class CLS
{
public:
static int iA;
static void iAplus()
{
++iA;
cout << "iA: " << iA << endl;
}
};
int CLS::iA = 0; // static변수 초기화
void main()
{
CLS::iAplus();
cout <<"iA: "<<CLS::iA << endl;
}
#복사생성자
-> 생성자의 인자로 객체를 전달 받아 인자로 받은 객체의 값을 복사한다.
이때 복사 생성자가 정의되지 않은 경우 컴파일러가 디폴드 복사생성자를 생성하여 호출하게 된다.
#include "stdafx.h"
class CLS
{
int m_iA;
int m_iB;
public:
CLS(int _a, int _b)
:m_iA(_a),m_iB(_b)
{
}
//복사 생성자
//CLS(CLS& _cls)
//{
// m_iA = _cls.m_iA; // 이때 왼쪽의 m_iA는 this->m_iA이다.
// m_iB = _cls.m_iB;
//}
void Func()
{
cout << "iA: " << m_iA << endl;
cout << "iB: " << m_iB << endl;
}
};
void main()
{
CLS cls(10, 20);
cls.Func();
CLS cls2(cls); // 디폴트 복사생성자로 복사되어 같은 값이 나옴
cls2.Func();
}
복사 생성자의 호출시점
1. 먼저 생성한 객체를 나중에 생성하는 객체의 생성자로 전달하는 경우 (위의 경우)
2. 함수의 매개 변수로 객체가 전달되는 경우
3. 함수의 반환 타입으로 객체가 반환되는 경우
위에서 복사 생성자의 인자로 레퍼런스(&)를 사용하는 이유는
위의 복사 생성자의 호출시점을 보면 알 수 있다.
레퍼런스를 사용하지 않을 경우, 복사생성자가 생성되고 난 뒤
복사생성자의 영역(stack)에 그 객체를 또 복사 해야되고
이런식으로 무한 반복으로 빠지게 되기 때문에 레퍼런스를 이용 해주는 것이다.
#디폴트복사(단순복사)의 문제점
단순 복사를 할 경우
힙영역에 객체 생성 후, 그 영역의 주소를 복사하는 방식을 취하기 때문에
다른 객체가 같은 주소를 가지게 된다.
그렇게 되면 객체 소멸 시 delete를 하게 될 때
같은 주소를 두번 지우게 되는 경우가 생겨서 오류가 발생할 수 있다.
#include "stdafx.h"
class CLS
{
char* szName;
public:
CLS(char* _szName)
{
szName = new char[strlen(_szName) + 1];
}
~CLS() // 소멸자
{
delete szName;
szName = nullptr;
}
CLS(CLS& _obj)
{
////단순복사(디폴트복사)
//szName = _obj.szName;
szName = new char[strlen(_obj.szName) + 1];
strcpy_s(szName, strlen(_obj.szName) + 1, _obj.szName);
}
};
void main()
{
CLS cls("Hi");
CLS cls2(cls);
}
#extern
-> 외부파일 어딘가에 전역 변수/함수가 있다고 알려주는 역할이다.
extern 선언은 메모리에 등록되지 않는다.
모든파일에 extern선언이 필요하며,
헤더파일을 만들어서 extern 선언을 해주면 더 편하다.
선언은
extern 자료형 변수명;
으로 해준다.