복사 생성자
인스턴스의 사본을 만드는 것.
만약 들고 있는 것이 레퍼런스라면, 레퍼런스의 주소값을 복사해줄 것인지의 문제가 있다.
// Vector.h
class Vector
{
public:
Vector(const Vector& other);
private:
int mX;
int mY;
};
// Vector.cpp
Vector::Vector(const Vector& other)
: mX(other.mX)
, mY(other.mY) // private 이지만, 같은 class 이기 때문에 접근 가능하다.
{
}
같은 클래스의 다른 개체를 이용하여 새로운 개체를 초기화하는 것은 다음과 같다.
Vector(const Vector& other);
Vector a; // default constructor 또는 매개변수 없는 생성자 호출
Vector b(a); // copy constructor
암시적 복사 생성자
암시적 복사 생성자는 코드에 복사 생성자가 없는 경우, 컴파일러가 암시적으로 생성해준다.
Vector() {}
Vector(const Vector& other)
: mX(other.mX)
, mY(other.mY)
{
}
이 경우 얕은 복사를 수행한다.
- 멤버 별로 복사한다.
- 각 멤버의 값을 복사한다.
- 개체인 멤버 변수는 해당 개체의 복사 생성자가 호출된다.
포인터 변수의 복사를 보기 위한 예제
// ClassRecode.h
class ClassRecode
{
public:
ClassRecord(const int *scores, int count);
~ClassRecord();
private:
int mCount;
int *mScores;
};
// ClassRecord.cpp
ClassRecord::ClassRecord(const int* scores, int count)
: mCount(count)
{
mScores = new int[mCount];
memcpy(mScores, scores, mCount * sizeof(int));
}
ClassRecord::~ClassRecord()
{
delete[] mScores;
}
포인터는 얕은 복사가 되기 때문에 주의가 필요하다.
// ClassRecord.cpp
ClassRecord::ClassRecord(const int* scores, int count)
: mCount(count)
{
mScores = new int[mCount];
memcpy(mScores, scores, mCount * sizeof(int));
}
// 컴파일러가 만들어주는 암시적 복사 생성자
ClassRecord::ClassRecord(const ClassRecored& other)
: mCount(other.mCount)
, mScores(other.mScores)
{
}
// main.cpp
ClassRecord classRecord(scores, 5);
ClassRecord classRecordCopy = new ClassRecord(classRecord);
delete classRecordCopy;
- 첫 번째 오브젝트가 스택에 만들어진다.
classRecord의 생성자가 만들어지면서 sizeof(int) * 5 가 힙영역에 할당된다. - 두 번째 오브젝트가 classRecord의 값을 복사하면서 힙에 만들어진다.
여기서 int*의 값은 classRecord가 가리키고 있는 힙영역의 int 배열의 위치와 같다. - 힙에 할당된 오브젝트가 삭제되면서 소멸자가 호출된다.
→ classRecord가 가리키고 있는 힙영역의 int 배열을 할당 해제한다.
사용자가 만드는 복사 생성자
- 클래스 안에서 동적할당을 한다면 얕은 복사가 일어날 가능성이 매우 높다.
- 깊은 복사를 하는 복사 생성자를 만들어주는 것이 안전하다.
- 포인터 변수가 가리키는 실제 데이터도 복사해주너야 한다.
ClassRecord::ClassRecord(const ClassRecord& other)
: mCount(other.mCount)
{
mScores = new int[mCount];
memcpy(mScores, other.mScores, mCount * sizeof(int));
}
'Language > C++' 카테고리의 다른 글
[C++] 15.Unmanaged Programming: 연산자 오버로딩 (0) | 2024.01.25 |
---|---|
[C++] 14.Unmanaged Programming: 함수 오버로딩 (0) | 2024.01.25 |
[C++] 12.Unmanaged Programming: 구조체 VS 클래스 (0) | 2024.01.25 |
[C++] 11.Unmanaged Programming: Const flag (0) | 2024.01.25 |
[C++] 10.Unmanaged Programming: 소멸자(Destructor) (0) | 2024.01.23 |