반응형
얕은 복사 (Shallow Copy)
• 메모리 자체를 복사 하지 않고 주소만 복사
• 일반적으로 「=」 연산자가 해당
[예제] 복사성생자 & 대입 연산자
#include <iostream>
class Point
{
int x = 0;
int y = 0;
public:
Point() = default;
Point(int x, int y) : x{ x }, y{ y } {}
};
int main()
{
Point p1{ 1, 1 };
Point p2 = p1; // 복사 생성자
p2 = p1; // 대입 연산자
}
Point 클래스 안에 x, y 는 각각 매핑되어 값이 복사되어 진다.
• 복사 생성자 = 객체 생성하면서 초기화
• 대입 연산자 = 객체 생성 후 넣는 것
(사용자가 만들지 않으면 컴파일러가 디폴트 복사 생성자 제공)
이러한 복사생성자/대입 연산자는 Primitive 타입에서는 괜찮지만
특정 특정 클래스에서는 문제 될 수 있다.
[예제] 복사 생성자의 얕은 복제
#include <iostream>
class vector
{
int* ptr;
std::size_t sz;
public:
vector(std::size_t sz, int value = 0) : sz(sz)
{
ptr = new int[sz];
for (std::size_t i; i < sz; i++)
{
ptr[i] = value;
}
}
~vector() { delete[] ptr; }
};
int main()
{
vector v1(5);
vector v2 = v1; // 복사 생성자 -> ??
}
vector v2 = v1; 에서
v2는 v1의 ptr, sz가 복사된다.
이때 배열을 가리키는 ptr 에 대해 생각해보면
배열 자체를 복사하는 것이 아니라 배열을 가리키는 포인터가 복사된다.
결과적으로 v1.ptr 과 v2.ptr은 동일한 배열을 가리키고 있다.
이 경우
• v1, v2 중 한쪽에서 변경하면 다른쪽도 같이 변경된다.
• 한쪽이 소멸되면 다른쪽도 더 이상 사용할 수 없다.
클래스 내부에 포인터 멤버가 있고
힙 메모리 등 자원을 사용한다면
컴파일러가 제공하는 대입 연산자는 얕은 복사 현상을 일으킨다.
그렇기에 사용자가 직접 복사 생성자(대입연산자)를 만드는 것이 좋다.
얕은 복사 해결 방법
• 깊은 복사 (Deep Copy)
• 복사 및 대입 금지 (= delete)
• 참조 계수 (Reference Counting)
• 소유권 이전
반응형
'프로그래밍 언어 > C++' 카테고리의 다른 글
[C++] 함수 객체 (function object) (2) | 2025.03.15 |
---|---|
[C++] 상속과 복사/대입 연산자 (0) | 2025.03.14 |
[C++] 스마트 포인터(Smart Pointer) 원리 (2) | 2025.03.12 |
[C++] 변환 연산자 conversion operator (6) | 2025.03.11 |
[C++] 다이아몬드 다중상속 (1) | 2025.03.10 |
댓글