[C++] 복사대입연산자와 복사 생성자, 얕은 복사와 깊은 복사, static
LastMod:
👨💻 개인 공부 기록용 블로그 입니다.
💡 틀린 내용이나 오타는 댓글, 메일로 제보해주시면 감사하겠습니다!! (__)
42 Cursus - Cpp Module을 진행하기 위해 정리했었던 C++98 기본 개념들로, C++11, C++14와 다른 내용이 있을 수 있습니다.
각 개념은 정리한 시간 순으로 배치되어 있으며, 한 포스트에 배치된 개념이 크게 관련이 없을 수 있습니다.
복사대입연산자(Copy Assignment Operator) 와 복사 생성자(Copy Constructor)
할당 연산자 (Assignment Operator)
- 할당 연산자는 크게 복사 할당 연산자(Copy Assignment Operator) 와 이동 대입 연산자 (Move Assignment Operator)로 나뉜다.
- 같은 Assignment를 입맛에 맞게 적절하다고 생각되는 단어로 번역했다.
- 이동 대입 연산자는 최적화를 위한 항목이고, C++98에서는 정의되지 않으니, 복사하지 않고 그대로 옮긴다는 의미로만 받아들이고 일단 넘어간다.
복사 할당 연산자 (Copy Assignment Operator)
- 이미 생성되어 있는 두 객체 사이에서 이뤄지는
=
연산.
Object o1;
Object o2;
o1 = o2; // Copy Assignment Operation
- 프로그래머가 정의하지 않아도, 컴파일러가 알아서 정의한다.
- 위의 예시에서는, o2의 멤버를 o1으로 복사하며, 이때 이뤄지는 복사를 얕은 복사(Shallow Copy)라고 한다.
복사 생성자 (Copy Constructor)
- 객체가 같은 클래스의 다른 객체에서 초기화 될 때 호출되는 생성자
class_name (const class_name& );
- 객체가 초기화 될 때 (
class a = b;
class a(b);
형태) - 함수의 인자로 전달될 때 (레퍼런스 제외)
- 새 객체를 같은 클래스의 기존 객체와 똑같이 초기화 할 때
- 주로 위 3가지 경우 호출된다.
- 컴파일러에 의해 복사 생성자가 호출되지 않는 경우가 있다. (최적화를 위하여)
Object o1(Object());
// 인자로 들어간 Object() 또한 생성자로, 결과는 익명 객체가 된다.
// 익명 객체의 생성자 -> o1의 복사 생성자 순으로 호출되어야 할 것 같지만,
// 어차피 익명 객체는 사라질 운명이기 때문에, 컴파일러는 익명 객체를 o1으로 만들어 버리고
// 복사 과정을 생략하여 최적화 한다. 컴파일러가 판단하여 발생하며, 이 과정은 항상 일어나지 않는다.
얕은 복사 (Shallow Copy)와 깊은 복사 (Deep Copy)
얕은 복사 (Shallow Copy)
- 컴파일러가 정의한 디폴트 복사 생성자에서 이뤄지는 복사 작업으로, 인수로 들어온 객체의 멤버 값을 복사하는 것을 뜻한다.
- 이 때, 복사를 받는 대상은 주소만을 저장한다. 참조 복사 라고도 한다.
깊은 복사 (Deep Copy)
- 주소를 복사하는 것이 아닌, 값을 복사하여 가지는 형태의 복사를 뜻한다.
- 얕은 복사와는 다르게, 깊은 복사는 복사된 값이 직접적으로 메모리에 적재된다.
int *a = new int(5);
int *b = new int(3);
a = b; // 얕은 복사 : a에 b가 가지고 있는 3에 대한 주소를 저장한다. 5에 대한 주소를 잃어버리기 때문에 누수가 발생.
*a = *b; // 깊은 복사 : b의 값을 가져와 a의 값을 교체한다. 값을 변경하는 연산이기에 누수가 발생하지 않는다.
Static Keyword
일반적인 정적 변수 (Static Variables)
- 정적 변수 (Static Variable) 또한 C에서의 정적 변수와 비슷하다.
- 데이터 메모리에 저장된다. 따로 초기화 하지 않으면 0으로 초기화된다.
- 연결을 가지지 않는 정적 변수는 블록 내부에서
static
키워드를 통해 정의한다. (C에서의 정적 변수) - 내부 연결을 가지는 정적 변수는 하나의 파일 내의 모든 블록에서 접근 및 사용이 가능하다.
- 전역 변수 처럼 선언하지만
static
키워드가 붙어있으며,extern
으로 다른 파일에서 가져갈 수 없다.
- 전역 변수 처럼 선언하지만
- 외부 연결을 가지는 정적 변수 = 전역 변수
정적 멤버 변수 (Static Member Variables)
- 클래스의 멤버 변수에
static
키워드가 붙은 것을 의미하며, 객체가 인스턴스화 되지 않아도 메모리에 적재되며 초기화된다. - 같은 종류의 모든 객체가 해당 변수를 공유하게 되며, 클래스 내부에선 선언만 할 수 있다.
- 멤버이므로 접근 지정자의 사용이 가능하다.
정적 멤버 함수 (Static Member Functions)
- 클래스의 멤버 함수에
static
키워드가 붙은 것을 의미하며, 객체가 인스턴스화 되지 않아도 사용 가능한 멤버 함수를 뜻한다. - 위 특성에 의하여, 클래스의 일반 멤버 변수, 함수에는 접근할 수 없다. 정적 멤버 변수에는 접근 가능하다.
- 또한,
this
포인터를 사용할 수 없다. 사용 시점 자체가 객체가 인스턴스화 되지 않을때 이기 때문이다.
Leave a comment