-
C++ Primer CH13. Copy Controlc++ 2024. 1. 21. 16:35
keywords: copy constructor, move constructor, copy-assignment operator, move-assignment operator, destructore
copy control
명시적으로 정의해놓지 않으면 컴파일러가 알아서 만들어서 사용함 → 오작동 가능성
13.1.1 The Copy Constructor
규칙1: copy constructor의 첫번째 인자는 무조건 참조자이다.
- 보통 const 붙인다.
The synthesized Copy Constructor
컴파일러가 자동생성해주는 것을 의미
default constructor과는 달리, 우리가 다른 copy constructor 명시적 정의해줘도 컴파일러가 생성해줌
copy constructor의 각각의 요소는 각자의 복사 규칙에 따라 복사가 이루어진다.
- built-in → 그냥 복사
- class → 해당 클래스의 copy constructor에 의해
- 배열,벡터 등 sequence containers → 각각의 요소의 copy constructor에 의해
초기화(initialization) → 처음에 정의 내릴 때 대입하는 것
할당 → 정의 내린 이후에 = 기호로 값을 교체해주는 것.
string s = "str" // 초기화 s = "aaa" // 할당
13.1.3 The destructor
static변수를 제외한 해당 객체의 모든 관련된 리소스를 파괴하는 함수
class Foo { public: ~Foo(); // destructor }
destructor는 파라미터를 받지 않기 때문에 overload할 수 없다.
- overload: 같은 이름의 함수를 파라미터만 다르게 하여 정의내리는 것
객체 인자로 보낼 때 value로 보내면 안됨.
class HasPtr { public: HasPtr(const std::string &s = std::string()): ps(new std::string(s)), i(0) {} ~HasPtr() {delete ps;} }; HasPtr f(HasPtr hp) { HasPtr ret = hp; return ret; } HasPtr p("some values"); f(p); // HasPtr q(p); // p, q는 invalid memory를 가리킨다.
passed by value라서 hp에 p 객체가 복사되었고, 함수 스코프 벗어나는 순간, ret와 hp가 파괴되면서 해당 객체의 destructor가 호출되며 p.ps가 가리키는 string 동적객체가 파괴된다.
13.1.5 Using = default
명시적으로 컴파일러에게 default copy control members 생성하라고 하는 것
13.1.6 Preventing Copies
iostream 클래스처럼 복사가 되지 않도록 하는 방법
- 왜 iostream은 복사 안되게 했나요?
- 복사해서 하나의 io buffer에서 여러 객체가 읽고 쓰고하는걸 방지하기 위함
= delete 사용
struct NoCopy { NoCopy() = default; NoCopy(const NoCopy&) = delete; NoCopy &operator=(const NoCopy&) = delete; ~NoCopy() = default; };
destructor은 delete하면 안됨 → 객체 파괴시킬 방법이 없어지기 때문
Writing Our Own swap Function
class HasPtr { friend void swap(HasPtr&, HasPtr&); }; inline void swap(HasPtr &lhs, HasPtr& rhs) { using std::swap; swap(lhs.ps, rhs.ps); swap(lsh.i, rhs.i); }
std::swap을 쓰면 안되고 위에서 커스텀한 swap을 써야 복사과정이 안 일어나고 참조만 교환되도록 할 수 있다.
void swap(Foo &lhs, Foo &rhs) { using std::swap; swap(lhs.h, rhs.h); }
이 코드에서 Foo는 HasPtr을 원소로 가지고 있고, HasPtr을 교환하는 swap함수이다.
using std::swap 해놓은 이유: HasPtr이 swap을 커스텀 정의내리지 않은 경우 대비
왜 using std::swap을 함수 스코프 내에 선언했는데 라이브러리 swap이 안쓰이고 HasPtr의 swap이 사용되는지.
rvalue reference는 곧 파괴될 객체를 참조한다.
→ 이 객체의 소유권은 줍는 사람이 임자다.
→ 객체를 훔친다
'c++' 카테고리의 다른 글
C++ 스터디. standard template library (1) 2024.01.21 C++ Primer CH15. Object-Oriented Programming (0) 2024.01.21 C++ Primer CH12. Dynamic Memory (0) 2024.01.21 C++ Primer CH11. Associative Containers (1) 2024.01.21 C++ Primer CH10. Generic Algorithms (0) 2024.01.21