C Programming Language/C++

C++ 객체 생성 κ·œμΉ™(생성, 볡사, 이동, μ†Œλ©Έ), μƒμ„±μž μ΄ˆκΈ°ν™”, μƒμ„±μž μ˜€λ²„λ‘œλ”©, μ •κ·œ νƒ€μž…

567Rabbit 2024. 8. 28. 21:46

객체 μƒμ„±μž(Object Constructors)와 μ†Œλ©Έμž(Destructor)

- μ˜¬λ°”λ₯΄κ²Œ λ™μž‘ν•˜λ €λ©΄ κΈ°λ³Έ 연산을 ν•˜λ‚˜λ„ κ΅¬ν˜„ν•˜μ§€ μ•Šκ±°λ‚˜ (0의 κ·œμΉ™) λͺ¨λ‘ κ΅¬ν˜„ (6의 κ·œμΉ™) ν•΄μ•Ό ν•œλ‹€

 

<the rule of zero>

- κΈ°λ³Έ 연산을 μ •μ˜ν•˜μ§€ μ•Šμ•„λ„ 되면 κ·Έλ ‡κ²Œ ν•˜λΌ

- κ°€μž₯ λ‹¨μˆœν•˜κ³ , λͺ…λ£Œν•œ 의미λ₯Ό μ€€λ‹€

 

<the rule of six>

- 볡사, 이동, μ†Œλ©Έμžμ˜ μ˜λ―ΈλŠ” μ„œλ‘œ λ°€μ ‘ν•˜κ²Œ μ—°κ΄€λ˜μ–΄ μžˆμ–΄, λ§Œμ•½ 이듀 쀑 ν•˜λ‚˜κ°€ μ„ μ–Έλ˜λ©΄, λ‹€λ₯Έ ν•¨μˆ˜λ“€λ„ κ³ λ €ν•  ν•„μš”κ°€ μžˆλ‹€

- 볡사/이동/μ†Œλ©Έμž ν•¨μˆ˜λ₯Ό =default λ˜λŠ” =delete둜 μ„ μ–Έν•˜λ©΄, μ»΄νŒŒμΌλŸ¬λŠ” 이동 μƒμ„±μž 및 이동 ν• λ‹Ή μ—°μ‚°μžμ˜ λ¬΅μ‹œμ  선언이 μ•ˆλœλ‹€.

- 이동 μƒμ„±μž λ˜λŠ” 이동 ν• λ‹Ή μ—°μ‚°μžλ₯Ό =default λ˜λŠ” =delete둜 μ„ μ–Έν•˜λ©΄, λ¬΅μ‹œμ μœΌλ‘œ μƒμ„±λœ 볡사 μƒμ„±μž λ˜λŠ” 볡사 ν• λ‹Ή μ—°μ‚°μžκ°€ μ‚­μ œλœ κ²ƒμœΌλ‘œ μ •μ˜λœλ‹€

- 이듀 쀑 ν•˜λ‚˜κ°€ μ„ μ–Έλ˜μžλ§ˆμž λ‚˜λ¨Έμ§€λŠ” λͺ¨λ‘ μ„ μ–Έν•΄μ•Ό ν•œλ‹€. λͺ¨λ“  잠재적인 이동을 더 λΉ„μ‹Ό λ³΅μ‚¬λ³ΈμœΌλ‘œ λ°”κΎΈκ±°λ‚˜ 클래슀λ₯Ό 이동 μ „μš©μœΌλ‘œ λ§Œλ“œλŠ” 것과 같은 μ›μΉ˜μ•ŠλŠ” 효과λ₯Ό ν”Όν•˜κΈ° μœ„ν•΄μ„œμ΄λ‹€.

 

 

 

 

 

6가지 κΈ°λ³Έ μ—°μ‚°μž(default operations) 와 μ†Œλ©Έμž(Destructor)

 

 

(1) κΈ°λ³Έ μƒμ„±μž (Default Constructor)

  • μ„€λͺ…: λ§€κ°œλ³€μˆ˜κ°€ μ—†λŠ” μƒμ„±μž. 클래슀 객체λ₯Ό μ΄ˆκΈ°ν™”ν•  λ•Œ ν˜ΈμΆœλœλ‹€
  • μ—­ν• : 객체λ₯Ό 초기 μƒνƒœλ‘œ μ΄ˆκΈ°ν™”ν•˜λŠ” 역할을 ν•œλ‹€
  • μžλ™ 생성 쑰건: ν΄λž˜μŠ€μ— μ‚¬μš©μžκ°€ μƒμ„±μžλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©΄, μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ κΈ°λ³Έ μƒμ„±μžλ₯Ό μƒμ„±ν•œλ‹€
class MyClass {
public:
    MyClass() = default;  // κΈ°λ³Έ μƒμ„±μž
};
MyClass obj;  // κΈ°λ³Έ μƒμ„±μžκ°€ ν˜ΈμΆœλ©λ‹ˆλ‹€.

 

 

(2) μ†Œλ©Έμž (Destructor)

  • μ„€λͺ…: 객체가 λ²”μœ„λ₯Ό λ²—μ–΄λ‚˜κ±°λ‚˜ μ‚­μ œλ  λ•Œ ν˜ΈμΆœλ˜λŠ” ν•¨μˆ˜.
  • μ—­ν• : 객체가 μ†Œλ©Έλ  λ•Œ λ¦¬μ†ŒμŠ€λ₯Ό ν•΄μ œν•˜κ±°λ‚˜, 정리 μž‘μ—…μ„ μˆ˜ν–‰ν•œλ‹€.
  • μžλ™ 생성 쑰건: ν΄λž˜μŠ€μ— μ‚¬μš©μžκ°€ μ†Œλ©Έμžλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©΄, μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ μ†Œλ©Έμžλ₯Ό μƒμ„±ν•œλ‹€.
  • 였직 ν•˜λ‚˜λ§Œ μ‘΄μž¬ν•˜λ©° νŒŒλΌλ―Έν„°λŠ” μ—†λ‹€
class MyClass {
public:
    ~MyClass() {
        // λ¦¬μ†ŒμŠ€ ν•΄μ œ μ½”λ“œ
    }
};
MyClass obj;  // λ²”μœ„λ₯Ό λ²—μ–΄λ‚˜λ©΄ μ†Œλ©Έμžκ°€ ν˜ΈμΆœλ©λ‹ˆλ‹€.

 

 

(3) 볡사 μƒμ„±μž (Copy Constructor)

  • μ„€λͺ…: λ‹€λ₯Έ κ°μ²΄λ‘œλΆ€ν„° λ³΅μ‚¬ν•˜μ—¬ μƒˆλ‘œμš΄ 객체λ₯Ό 생성할 λ•Œ ν˜ΈμΆœλ˜λŠ” μƒμ„±μž.
  • μ—­ν• : κΈ°μ‘΄ 객체의 값을 λ³΅μ‚¬ν•˜μ—¬ μƒˆλ‘œμš΄ 객체λ₯Ό μ΄ˆκΈ°ν™”ν•œλ‹€
  • μžλ™ 생성 쑰건: ν΄λž˜μŠ€μ— μ‚¬μš©μžκ°€ 볡사 μƒμ„±μžλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©΄, μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ 볡사 μƒμ„±μžλ₯Ό 생성함
class MyClass {
public:
    MyClass(const MyClass& other) {
        // 볡사 생성 μ½”λ“œ
    }
};
MyClass obj1;
MyClass obj2 = obj1;  // 볡사 μƒμ„±μžκ°€ ν˜ΈμΆœλ©λ‹ˆλ‹€.

 

- κ°’ νƒ€μž…μ€ 일반적으둜 볡사 κ°€λŠ₯ν•΄μ•Ό ν•˜λ©° κ°’ νƒ€μž…μ€ λ‚΄μš©(contents)에 κ΄€ν•œ κ²ƒμœΌλ‘œ κ°’ νƒ€μž…μ΄ λ³΅μ‚¬λ˜λ©΄ 항상 두 개의 독립적인 값이 생기고 각자 μˆ˜μ •λ  수 μžˆμ–΄μ•Ό ν•œλ‹€.  예λ₯Ό λ“€μ–΄, intλ‚˜ double 같은 κΈ°λ³Έ νƒ€μž…μ€ λ³΅μ‚¬ν•˜λ©΄ 두 개의 독립적인 값이 생긴닀. ν•˜λ‚˜μ˜ 값을 바꾸더라도 λ‹€λ₯Έ κ°’μ—λŠ” 영ν–₯을 주지 μ•ŠλŠ”λ‹€.

 

(μ˜ˆμ™Έ) -  클래슀 κ³„μΈ΅κ΅¬μ‘°μ˜ μΈν„°νŽ˜μ΄μŠ€: 볡사가 κΌ­ ν•„μš”ν•˜μ§€ μ•Šκ±°λ‚˜, μ›μΉ˜ μ•ŠλŠ” 상황도 μžˆλ‹€.

              예λ₯Ό λ“€μ–΄, μ–΄λ–€ ν΄λž˜μŠ€λŠ” λ³΅μ‚¬ν•˜λŠ” λŒ€μ‹ μ— μ°Έμ‘°λ‚˜ 포인터λ₯Ό 톡해 μ ‘κ·Όν•˜λŠ” 것이 더 효율적일 수 μžˆλ‹€.

           - λ¦¬μ†ŒμŠ€ ν•Έλ“€(파일, μ†ŒμΌ“ λ“±)은 볡사 κ°€λŠ₯ν•  μˆ˜λ„ 있고 그렇지 μ•Šμ„ μˆ˜λ„ 있음

           - 논리적, μ„±λŠ₯μƒμ˜ 이유둜 이동(move)ν•˜λ„λ‘ νƒ€μž…μ΄ μ •μ˜λ  수 있음

( std::unique_ptr처럼, 볡사 λŒ€μ‹  이동을 μš”κ΅¬ν•˜λŠ” νƒ€μž…λ„ μžˆλ‹€. μ΄λŸ¬ν•œ νƒ€μž…μ€ ν•œ λ²ˆμ— ν•˜λ‚˜μ˜ 객체만 λ¦¬μ†ŒμŠ€λ₯Ό κ°€μ§ˆ 수 μžˆλ„λ‘ μ„€κ³„λ˜μ—ˆλ‹€. λ³΅μ‚¬ν•˜λŠ” λŒ€μ‹ , μ†Œμœ κΆŒμ„ λ‹€λ₯Έ 객체둜 "이동"μ‹œν‚€λŠ” 것이 더 μ ν•©ν•œ 경우 )

 

 

 

(4) 볡사 λŒ€μž… μ—°μ‚°μž (Copy Assignment Operator)

  • μ„€λͺ…: ν•˜λ‚˜μ˜ 객체λ₯Ό λ‹€λ₯Έ 객체에 λŒ€μž…ν•  λ•Œ ν˜ΈμΆœλ˜λŠ” μ—°μ‚°μž.
  • μ—­ν• : κΈ°μ‘΄ 객체의 값을 λ‹€λ₯Έ 객체둜 볡사.
  • μžλ™ 생성 쑰건: ν΄λž˜μŠ€μ— μ‚¬μš©μžκ°€ 볡사 λŒ€μž… μ—°μ‚°μžλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©΄, μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ 볡사 λŒ€μž… μ—°μ‚°μžλ₯Ό μƒμ„±ν•œλ‹€
class MyClass {
public:
    MyClass& operator=(const MyClass& other) {
        // 볡사 λŒ€μž… μ½”λ“œ
        return *this;
    }
};
MyClass obj1, obj2;
obj1 = obj2;  // 볡사 λŒ€μž… μ—°μ‚°μžκ°€ ν˜ΈμΆœλ©λ‹ˆλ‹€.

 

 

(5) 이동 μƒμ„±μž (Move Constructor)

  • μ„€λͺ…: μž„μ‹œ κ°μ²΄λ‚˜ μ†Œμœ κΆŒμ΄ μ΄μ „λ˜λŠ” κ°μ²΄λ‘œλΆ€ν„° μžμ›μ„ μ΄λ™ν•˜μ—¬ μƒˆλ‘œμš΄ 객체λ₯Ό 생성할 λ•Œ ν˜ΈμΆœλ˜λŠ” μƒμ„±μž.
  • μ—­ν• : μžμ›μ˜ 볡사 λŒ€μ‹  이동을 톡해 μ„±λŠ₯을 μ΅œμ ν™”
  • μžλ™ 생성 쑰건: ν΄λž˜μŠ€μ— μ‚¬μš©μžκ°€ 이동 μƒμ„±μžλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©΄, μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ 이동 μƒμ„±μžλ₯Ό 생성.단, ν΄λž˜μŠ€κ°€ 볡사 μƒμ„±μžλ‚˜ 볡사 λŒ€μž… μ—°μ‚°μžλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ •μ˜ν•˜μ§€ μ•Šμ•˜μ„ λ•Œλ§Œ μƒμ„±λœλ‹€
class MyClass {
public:
    MyClass(MyClass&& other) noexcept {
        // 이동 생성 μ½”λ“œ
    }
};
MyClass obj1 = MyClass();  // 이동 μƒμ„±μžκ°€ ν˜ΈμΆœλ©λ‹ˆλ‹€. μš°μΈ‘κ°’(rvalue)으둜 객체λ₯Ό μƒμ„±ν•˜λŠ” 방법

 

- 이동 μƒμ„±μžλŠ” 객체λ₯Ό λ³΅μ‚¬ν•˜λŠ” λŒ€μ‹ , μš°μΈ‘κ°’(rvalue) 객체의 μžμ›μ„ μ΄λ™μ‹œμΌœ μƒˆλ‘œμš΄ 객체λ₯Ό μƒμ„±ν•˜λŠ” μƒμ„±μžμ΄λ‹€. μ΄λŠ” κΉŠμ€ 볡사(deep copy)보닀 더 효율적으둜 μžμ›μ„ 관리할 수 μžˆλ‹€. 특히, λŒ€λŸ‰μ˜ 데이터λ₯Ό λ‹€λ£¨κ±°λ‚˜ 동적 λ©”λͺ¨λ¦¬ 할당이 λ§Žμ€ 경우 이동 μƒμ„±μžλŠ” 큰 μ„±λŠ₯ 이점을 μ œκ³΅ν•œλ‹€.

- μš°μΈ‘κ°’(rvalue)은 더 이상 ν•„μš”ν•˜μ§€ μ•Šκ±°λ‚˜ μž„μ‹œμ μœΌλ‘œ μ‚¬μš©λ˜λŠ” κ°’μ΄λ―€λ‘œ, λΆˆν•„μš”ν•œ 볡사λ₯Ό ν”Όν•˜κ³  객체의 μžμ›μ„ 효율적으둜 관리할 수 μžˆλ‹€. 예λ₯Ό λ“€μ–΄, 큰 데이터λ₯Ό ν¬ν•¨ν•˜λŠ” 객체λ₯Ό λ³΅μ‚¬ν•˜λŠ” λŒ€μ‹ , 이동을 톡해 더 λΉ λ₯΄κ²Œ μƒˆλ‘œμš΄ 객체λ₯Ό 생성할 수 μžˆλ‹€.

 

 

C++ Shallow Copy(얕은 볡사)와 Deep Copy(κΉŠμ€ 볡사)

Shallow Copy(얕은 볡사) Shallow Copy(얕은 볡사)λŠ” λ©”λͺ¨λ¦¬ μ£Όμ†Œλ§Œ λ³΅μ‚¬ν•˜μ—¬, 원본 객체와 λ³΅μ‚¬λœ 객체가 같은 λ©”λͺ¨λ¦¬λ₯Ό κ³΅μœ ν•˜κ²Œ ν•œλ‹€. μ΄λŠ” μ˜λ„μΉ˜ μ•Šμ€ 데이터 변경을 μ΄ˆλž˜ν•  수 μžˆλ‹€.   객체의 데

codebunny99.tistory.com

 

 

 

(6) 이동 λŒ€μž… μ—°μ‚°μž (Move Assignment Operator)

  • μ„€λͺ…: ν•˜λ‚˜μ˜ κ°μ²΄λ‘œλΆ€ν„° λ‹€λ₯Έ 객체둜 μžμ›μ„ 이동할 λ•Œ ν˜ΈμΆœλ˜λŠ” μ—°μ‚°μž.
  • μ—­ν• : μžμ›μ˜ 볡사 λŒ€μ‹  이동을 톡해 μ„±λŠ₯을 μ΅œμ ν™”
  • μžλ™ 생성 쑰건: ν΄λž˜μŠ€μ— μ‚¬μš©μžκ°€ 이동 λŒ€μž… μ—°μ‚°μžλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ •μ˜ν•˜μ§€ μ•ŠμœΌλ©΄, μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ 이동 λŒ€μž… μ—°μ‚°μžλ₯Ό 생성. 단, ν΄λž˜μŠ€κ°€ 볡사 μƒμ„±μžλ‚˜ 볡사 λŒ€μž… μ—°μ‚°μžλ₯Ό λͺ…μ‹œμ μœΌλ‘œ μ •μ˜ν•˜μ§€ μ•Šμ•˜μ„ λ•Œλ§Œ μƒμ„±λœλ‹€
class MyClass {
public:
    MyClass& operator=(MyClass&& other) noexcept {
        // 이동 λŒ€μž… μ½”λ“œ
        return *this;
    }
};
MyClass obj1, obj2;
obj1 = std::move(obj2);  // 이동 λŒ€μž… μ—°μ‚°μžκ°€ ν˜ΈμΆœλ©λ‹ˆλ‹€.

 

 

< C+11 λ„μž… κ°œλ… : noexcept >

 

이동 μƒμ„±μžμ™€ 이동 ν• λ‹Ή μ—°μ‚°μžμ—μ„œ μ˜ˆμ™Έκ°€ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ noexcept ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬μ•Ό ν•œλ‹€

noexceptλŠ” ν•¨μˆ˜κ°€ μ˜ˆμ™Έλ₯Ό λ˜μ§€μ§€ μ•ŠλŠ”λ‹€λŠ” 것을 μ»΄νŒŒμΌλŸ¬μ—κ²Œ μ•Œλ¦¬λŠ” ν‚€μ›Œλ“œ. 즉, noexceptκ°€ 뢙은 ν•¨μˆ˜λŠ” μ˜ˆμ™Έκ°€ λ°œμƒν•˜μ§€ μ•Šμ„ 것을 보μž₯ν•œλ‹€

 

 

μ™œ noexceptλ₯Ό μ‚¬μš©ν•˜λŠ”κ°€?

  • μ•ˆμ „μ„±: 이동 μ—°μ‚°μ—μ„œ μ˜ˆμ™Έκ°€ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ 보μž₯ν•˜μ—¬ ν”„λ‘œκ·Έλž¨μ΄ μ˜ˆμ™Έλ‘œ 인해 예기치 μ•Šκ²Œ μ€‘λ‹¨λ˜λŠ” 상황을 방지
  • μ„±λŠ₯ μ΅œμ ν™”: ν‘œμ€€ λΌμ΄λΈŒλŸ¬λ¦¬μ™€ 같은 μ—¬λŸ¬ ν•¨μˆ˜(특히 벑터, 리슀트 λ“±μ˜ μ»¨ν…Œμ΄λ„ˆ)λŠ” 이동 μƒμ„±μžλ‚˜ 이동 ν• λ‹Ή μ—°μ‚°μžκ°€ noexcept둜 ν‘œμ‹œλ˜μ–΄ μžˆλŠ” κ²½μš°μ—λ§Œ 이동을 μ‚¬μš©ν•œλ‹€. λ§Œμ•½ noexceptκ°€ μ—†λ‹€λ©΄, 볡사 연산을 μ‚¬μš©ν•  μˆ˜λ°–μ— μ—†κΈ° λ•Œλ¬Έμ— μ„±λŠ₯이 μ €ν•˜λ  수 μžˆλ‹€.
  • 예λ₯Ό λ“€μ–΄, 벑터가 λ‚΄λΆ€μ μœΌλ‘œ λ©”λͺ¨λ¦¬λ₯Ό ν™•μž₯ν•  λ•Œ, κΈ°μ‘΄ μš”μ†Œλ“€μ„ μƒˆλ‘œμš΄ λ©”λͺ¨λ¦¬ κ³΅κ°„μœΌλ‘œ 이동해야 ν•œλ‹€. 이 κ³Όμ •μ—μ„œ 이동 연산이 μ˜ˆμ™Έλ₯Ό 던질 수 μžˆλ‹€λ©΄, λ²‘ν„°λŠ” 볡사 연산을 μ‚¬μš©ν•΄μ•Όλ§Œ ν•œλ‹€. λ³΅μ‚¬λŠ” 이동보닀 훨씬 λΉ„μš©μ΄ 많이 λ“ λ‹€
class MyClass {
public:
    MyClass(MyClass&& other) noexcept {  // 이동 μƒμ„±μžμ— noexcept μΆ”κ°€
        // μžμ›μ„ μ΄λ™ν•˜λŠ” μ½”λ“œ
    }

    MyClass& operator=(MyClass&& other) noexcept {  // 이동 ν• λ‹Ή μ—°μ‚°μžμ— noexcept μΆ”κ°€
        if (this != &other) {
            // μžμ› 이동 μ½”λ“œ
        }
        return *this;
    }

 

 

 

 

 

μ •κ·œ νƒ€μž…(regular type)

 

μ •κ·œ νƒ€μž…(Regular Type)은 C++와 같은 ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ—μ„œ νŠΉμ • 객체 νƒ€μž…μ΄ μΌκ΄€λ˜κ³  μ˜ˆμƒ κ°€λŠ₯ν•œ λ°©μ‹μœΌλ‘œ λ™μž‘ν•˜λŠ”μ§€ ν™•μΈν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ˜λŠ” κ°œλ…μ΄λ‹€. μ •κ·œ νƒ€μž…μ€ λ‹€μŒκ³Ό 같은 μ—°μ‚°κ³Ό 행동을 μ§€μ›ν•˜κ³ , μ΄λŸ¬ν•œ 연산이 μ§κ΄€μ μœΌλ‘œ μ˜ˆμƒλ˜λŠ” λ°©μ‹μœΌλ‘œ μž‘λ™ν•΄μ•Ό ν•œλ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€

 

μ •κ·œ νƒ€μž…(Regular Type)은 볡사 κ°€λŠ₯μ„±, 동등성 비ꡐ, 그리고 μΌκ΄€λœ ꡬ쑰적 κ·œμΉ™μ„ λ§Œμ‘±ν•΄μ•Ό ν•œλ‹€. 이 κ°œλ…μ€ μ½”λ“œμ—μ„œ 예츑 κ°€λŠ₯ν•œ λ™μž‘μ„ 보μž₯ν•˜κ³ , 객체 κ°„μ˜ μƒν˜Έμž‘μš©μ„ 직관적이고 λͺ…ν™•ν•˜κ²Œ λ§Œλ“ λ‹€. int νƒ€μž…μ€ μ •κ·œ νƒ€μž…μ˜ 쒋은 예둜, 볡사와 비ꡐ가 κ°€λŠ₯ν•˜λ©°, μ΄λŸ¬ν•œ 연산이 μ§κ΄€μ μœΌλ‘œ μž‘λ™ν•œλ‹€.

이와 같은 μ •κ·œ νƒ€μž…μ˜ κ°œλ…μ„ λ”°λ¦„μœΌλ‘œμ¨, ν”„λ‘œκ·Έλž˜λ°μ—μ„œ λ”μš± κ²¬κ³ ν•˜κ³  μœ μ§€λ³΄μˆ˜ν•˜κΈ° μ‰¬μš΄ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.

 

 

1. 볡사 κ°€λŠ₯μ„± (Copyability)

μ •κ·œ νƒ€μž…μ€ 볡사 κ°€λŠ₯ν•΄μ•Ό ν•œλ‹€. 즉, 객체λ₯Ό λ‹€λ₯Έ 객체에 볡사할 수 μžˆμ–΄μ•Ό ν•˜λ©°, λ³΅μ‚¬λœ κ°μ²΄λŠ” 원본 객체와 λ™μΌν•œ 값을 κ°€μ Έμ•Ό ν•œλ‹€

int a = 10;
int b = a;  // bλŠ” a의 볡사본, b == 10

 

 

2. 동등성 비ꡐ (Equality Comparison)

μ •κ·œ νƒ€μž…μ€ 동등성 비ꡐ μ—°μ‚°μž (==)λ₯Ό 지원해야 ν•œλ‹€. 즉, 두 객체가 λ™μΌν•œμ§€λ₯Ό 비ꡐ할 수 μžˆμ–΄μ•Ό ν•˜λ©°, 이 연산은 μ§κ΄€μ μœΌλ‘œ μ˜ˆμƒλ˜λŠ” κ²°κ³Όλ₯Ό λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€.

int x = 5;
int y = 5;
bool isEqual = (x == y);  // isEqual은 true

 

 

3. ꡬ쑰적 κ·œμΉ™ (Structural Rules)

μ •κ·œ νƒ€μž…μ€ 일반적으둜 λ‹€μŒκ³Ό 같은 ꡬ쑰적 κ·œμΉ™μ„ 따라야 ν•œλ‹€

  • 볡사 μƒμ„±μžμ™€ 볡사 λŒ€μž… μ—°μ‚°μžλŠ” ν•΄λ‹Ή 객체의 λͺ¨λ“  데이터λ₯Ό μ •ν™•ν•˜κ²Œ 볡사해야 ν•œλ‹€
  • == μ—°μ‚°μžμ™€ != μ—°μ‚°μžλŠ” λ…Όλ¦¬μ μœΌλ‘œ μΌκ΄€λœ κ²°κ³Όλ₯Ό λ°˜ν™˜ν•΄μ•Ό ν•œλ‹€. 즉, a == bκ°€ 참이면 a != bλŠ” 거짓이어야 ν•œλ‹€.
  • μ •κ·œ νƒ€μž…μ˜ κ°μ²΄λŠ” 볡사와 비ꡐ 외에도 κ°’μ˜ 일관성을 μœ μ§€ν•΄μ•Ό ν•˜λ©°, μ˜ˆμƒμΉ˜ λͺ»ν•œ λ™μž‘μ„ ν•˜μ§€ μ•Šμ•„μ•Ό ν•œλ‹€
struct Point {
    int x, y;
    bool operator==(const Point& other) const {
        return x == other.x && y == other.y;
    }
};
Point p1 = {1, 2};
Point p2 = p1;  // p2λŠ” p1의 볡사본
bool isEqual = (p1 == p2);  // isEqual은 true

 

 

< μ •κ·œ νƒ€μž…μ˜ μ˜ˆμ‹œ: int >

  ex) int νƒ€μž…μ€ μ •κ·œ νƒ€μž…μ˜ λͺ¨λ“  기쀀을 μΆ©μ‘±ν•˜λŠ” 쒋은 μ˜ˆμ΄λ‹€:

- 볡사 κ°€λŠ₯μ„±: int νƒ€μž…μ˜ λ³€μˆ˜λŠ” λ‹€λ₯Έ λ³€μˆ˜λ‘œ 볡사할 수 있으며, λ³΅μ‚¬λœ λ³€μˆ˜λŠ” 원본 λ³€μˆ˜μ™€ λ™μΌν•œ 값을 가진닀.

- 동등성 비ꡐ: int νƒ€μž…μ˜ λ³€μˆ˜λ“€μ€ == μ—°μ‚°μžλ‘œ 비ꡐ할 수 있으며, λ…Όλ¦¬μ μœΌλ‘œ μΌκ΄€λœ κ²°κ³Όλ₯Ό μ œκ³΅ν•œλ‹€

- ꡬ쑰적 κ·œμΉ™: int νƒ€μž…μ€ κΈ°λ³Έ νƒ€μž…μœΌλ‘œ μ •μ˜λ˜μ–΄ 있으며, 볡사와 비ꡐ λ™μž‘μ΄ μΌκ΄€λ˜κ³  예츑 κ°€λŠ₯ν•˜κ²Œ μ •μ˜λ˜μ–΄ μžˆλ‹€.

 

 

 

 

 

 

μƒμ„±μž μ˜€λ²„λ‘œλ”©(Constructor Overloading)

 

λ™μΌν•œ 클래슀 내에 μ—¬λŸ¬ 개의 μƒμ„±μžλ₯Ό μ •μ˜ν•˜λŠ” 기법이닀. 각 μƒμ„±μžλŠ” λ§€κ°œλ³€μˆ˜μ˜ μˆ˜λ‚˜ νƒ€μž…μ΄ λ‹€λ₯΄κ²Œ μ •μ˜λ˜κ³  이λ₯Ό 톡해 객체λ₯Ό λ‹€μ–‘ν•œ λ°©μ‹μœΌλ‘œ μ΄ˆκΈ°ν™”ν•  수 μžˆλ‹€. μ»΄νŒŒμΌλŸ¬λŠ” 객체λ₯Ό 생성할 λ•Œ 제곡된 μΈμˆ˜μ— 따라 μ μ ˆν•œ μƒμ„±μžλ₯Ό μžλ™μœΌλ‘œ μ„ νƒν•œλ‹€.

μ‰½κ²Œ 말해, 같은 이름을 가진 μ—¬λŸ¬ 개의 μƒμ„±μžλ₯Ό λ§Œλ“œλŠ” 것을 μ˜λ―Έν•œλ‹€. 이 μƒμ„±μžλ“€μ€ μ„œλ‘œ λ‹€λ₯Έ λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•΄ 객체λ₯Ό λ‹€μ–‘ν•œ λ°©μ‹μœΌλ‘œ μ΄ˆκΈ°ν™”ν•  수 μžˆλ‹€.

class Rectangle {
private:
    int width;
    int height;

public:
    // 1. κΈ°λ³Έ μƒμ„±μž (Default Constructor)
    // λ§€κ°œλ³€μˆ˜κ°€ μ—†λŠ” μƒμ„±μžμž…λ‹ˆλ‹€. 
    // Rectangle()처럼 μΈμˆ˜κ°€ 없이 객체λ₯Ό 생성할 λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€. 객체λ₯Ό κΈ°λ³Έ μƒνƒœλ‘œ μ΄ˆκΈ°ν™”ν•©λ‹ˆλ‹€.
    Rectangle() {
        width = 0;
        height = 0;
    }

    // 2. λ§€κ°œλ³€μˆ˜κ°€ μžˆλŠ” μƒμ„±μž (Parameterized Constructor)
    // 인수둜 제곡된 값에 따라 객체의 멀버 λ³€μˆ˜λ₯Ό μ΄ˆκΈ°ν™”ν•©λ‹ˆλ‹€. 
    // μ—¬κΈ°μ„œλŠ” λ„ˆλΉ„μ™€ 높이λ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.
    Rectangle(int w, int h) {
        width = w;
        height = h;
    }

    // 3. 볡사 μƒμ„±μž (Copy Constructor)
    // κΈ°μ‘΄ 객체λ₯Ό λ³΅μ‚¬ν•˜μ—¬ μƒˆλ‘œμš΄ 객체λ₯Ό 생성할 λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€. 
    // 볡사 μƒμ„±μžλŠ” 객체λ₯Ό λ™μΌν•œ κ°’μœΌλ‘œ μ΄ˆκΈ°ν™”ν•΄μ•Ό ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€.
    Rectangle(const Rectangle &rect) {
        width = rect.width;
        height = rect.height;
    }

    void display() {
        std::cout << "Width: " << width << ", Height: " << height << std::endl;
    }
};

 

<μž₯점>

 

μœ μ—°μ„±: λ‹€μ–‘ν•œ λ°©μ‹μœΌλ‘œ 객체λ₯Ό μ΄ˆκΈ°ν™”ν•  수 μžˆμ–΄, μ‚¬μš©μžμ—κ²Œ 더 λ§Žμ€ 선택지λ₯Ό 제곡

μ½”λ“œμ˜ 가독성: 각 μƒμ„±μžκ°€ νŠΉμ •ν•œ μ΄ˆκΈ°ν™” λͺ©μ μ„ κ°€μ§€λ―€λ‘œ, μ½”λ“œμ˜ 가독성이 높아짐

μž¬μ‚¬μš©μ„±: λ™μΌν•œ 클래슀 λ‚΄μ—μ„œ λ‹€μ–‘ν•œ 상황에 λ§žλŠ” μ΄ˆκΈ°ν™” λ‘œμ§μ„ μ œκ³΅ν•¨μœΌλ‘œμ¨, 클래슀의 μž¬μ‚¬μš©μ„±μ΄ 증가

 

 

<μ£Όμ˜μ‚¬ν•­>

- μƒμ„±μž μ˜€λ²„λ‘œλ”©μ„ μ‚¬μš©ν•  λ•ŒλŠ” 각 μƒμ„±μžκ°€ μ„œλ‘œ λ‹€λ₯Έ μ‹œκ·Έλ‹ˆμ²˜(λ§€κ°œλ³€μˆ˜μ˜ μˆ˜λ‚˜ νƒ€μž…)λ₯Ό κ°€μ Έμ•Ό ν•œλ‹€.

- λ„ˆλ¬΄ λ§Žμ€ μƒμ„±μž μ˜€λ²„λ‘œλ”©μ€ 클래슀의 λ³΅μž‘μ„±μ„ μ¦κ°€μ‹œν‚¬ 수 μžˆμœΌλ―€λ‘œ, ν•„μš”ν•œ κ²½μš°μ—λ§Œ μ μ ˆν•˜κ²Œ μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

 

 

 

 

 

 

μƒμ„±μž μ΄ˆκΈ°ν™”

 

μƒμ„±μžλ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” 방법은 λ‹€μŒκ³Ό κ°™λ‹€. μ™Όμͺ½μ˜ μ½”λ“œλ₯Ό 였λ₯Έμͺ½ μ½”λ“œμ²˜λŸΌ κ°„νŽΈν•˜κ²Œ ν‘œν˜„ν•  수 μžˆλ‹€.

 

 

 

- μ˜λ„ν•˜μ§€ μ•Šμ€ ν˜•λ³€ν™˜μ„ ν”Όν•˜κΈ°

 

μƒμ„±μž μ΄ˆκΈ°ν™”λŠ” new ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄ 객체λ₯Ό 생성할 λ•Œ, κ·Έ 객체가 μ™„μ „νžˆ μ΄ˆκΈ°ν™”λœ μƒνƒœλ‘œ λ§Œλ“€μ–΄μ§€λ„λ‘ 보μž₯ν•˜λŠ” μž‘μ—…μ΄λ‹€. 이 λ•Œ, explicit ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ ν•΄λ‹Ή μƒμ„±μžλŠ” λͺ…μ‹œμ μœΌλ‘œ ν˜ΈμΆœλ˜μ–΄μ•Ό ν•˜λ©°, μ•”μ‹œμ  ν˜• λ³€ν™˜μ΄λ‚˜ μž„μ‹œ 객체 μƒμ„±μœΌλ‘œ ν˜ΈμΆœλ˜μ§€ μ•Šκ²Œ λœλ‹€. explicit ν‚€μ›Œλ“œλŠ” C++μ—μ„œ λ‹¨μΌ λ§€κ°œλ³€μˆ˜ μƒμ„±μžκ°€ μ•”μ‹œμ (implicit)으둜 ν˜ΈμΆœλ˜λŠ” 것을 λ°©μ§€ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λœλ‹€. explicit ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ©΄, μ»΄νŒŒμΌλŸ¬λŠ” 단일 λ§€κ°œλ³€μˆ˜ μƒμ„±μž(ν•˜λ‚˜μ˜ 인수만 λ°›μ•„μ„œ 객체λ₯Ό μ΄ˆκΈ°ν™”ν•˜λŠ” μƒμ„±μž)λ₯Ό μ‚¬μš©ν•΄ μ˜λ„ν•˜μ§€ μ•Šμ€ ν˜•λ³€ν™˜μ„ μžλ™μœΌλ‘œ μˆ˜ν–‰ν•  수 μžˆλ‹€.

λ•Œλ‘œλŠ” 이 μžλ™ λ³€ν™˜μ΄ μ˜λ„μΉ˜ μ•Šμ€ 버그λ₯Ό μœ λ°œν•  수 있기 λ•Œλ¬Έμ—, ν•„μš”μ— 따라 explicit ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ€‘μš”ν•˜λ‹€.

 

#include <iostream>

class MyClass {
public:
    // explicit ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œ 단일 λ§€κ°œλ³€μˆ˜ μƒμ„±μž
    explicit MyClass(int value) : value_(value) {
        std::cout << "MyClass μƒμ„±μž 호좜, κ°’: " << value_ << std::endl;
    }

    void display() const {
        std::cout << "MyClass 객체의 κ°’: " << value_ << std::endl;
    }

private:
    int value_;
};

int main() {
    // MyClass obj1 = 10;  // 였λ₯˜ λ°œμƒ: μ•”μ‹œμ  λ³€ν™˜μ΄ ν—ˆμš©λ˜μ§€ μ•ŠμŒ
    MyClass obj1(10);    // λͺ…μ‹œμ μœΌλ‘œ μƒμ„±μž 호좜
    obj1.display();

    MyClass obj2(20);    // λͺ…μ‹œμ μœΌλ‘œ μƒμ„±μž 호좜
    obj2.display();

    return 0;
}
#include <iostream>

class MyClass {
public:
    // explicit ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ§€ μ•Šμ€ 단일 λ§€κ°œλ³€μˆ˜ μƒμ„±μž
    MyClass(int value) : value_(value) {
        std::cout << "MyClass μƒμ„±μž 호좜, κ°’: " << value_ << std::endl;
    }

    void display() const {
        std::cout << "MyClass 객체의 κ°’: " << value_ << std::endl;
    }

private:
    int value_;
};

int main() {
    MyClass obj1 = 10;  // intλ₯Ό MyClass둜 μžλ™ λ³€ν™˜
    obj1.display();

    MyClass obj2(20);   // 일반적인 μƒμ„±μž 호좜
    obj2.display();

    return 0;
}

 

 

- 볡사 및 이동 μƒμ„±μžμ— 'explicit'을 μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 이유??

 

볡사 및 이동 μƒμ„±μžλŠ” μ›λž˜λΆ€ν„° μžλ™μœΌλ‘œ 객체 κ°„μ˜ ν˜•λ³€ν™˜μ„ μˆ˜ν–‰ν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€.

λ§Œμ•½ 이 μƒμ„±μžλ“€μ„ explicit으둜 μ„ μ–Έν•˜λ©΄, 값에 μ˜ν•œ 전달(pass-by-value) λ˜λŠ” λ°˜ν™˜(return by value)이 λ³΅μž‘ν•΄μ§€κ³  μ„±λŠ₯이 μ €ν•˜λ  수 μžˆλ‹€.

 

 

 

 

 

 

μ‚­μ œλœ μƒμ„±μž μ„ μ–Έν•˜κΈ°(Deleted Constructor)

 

μ‚­μ œλœ μƒμ„±μžλ₯Ό μ„ μ–Έν•˜λŠ” μ½”λ“œλŠ” μ†Œλ©Έμžμ™€λŠ” λ‹€λ₯Έ κ°œλ…μ΄λ‹€. μ‚­μ œλœ μƒμ„±μžλ₯Ό μ„ μ–Έν•˜λŠ” μ½”λ“œλŠ” νŠΉμ • μƒμ„±μžλ‚˜ μ—°μ‚°μž, ν•¨μˆ˜ 등을 λͺ…μ‹œμ μœΌλ‘œ μ‚¬μš©ν•  수 없도둝 λ§Œλ“€ λ•Œ μ‚¬μš©λœλ‹€. ( κΈ°λ³Έ μƒμ„±μžλ₯Ό μ‚¬μš©ν•˜μ§€ λͺ»ν•˜κ²Œ ν•  λ•Œ, νŠΉμ • 볡사 μƒμ„±μžλ‚˜ 볡사 μ—°μ‚°μžλ₯Ό μ‚­μ œν•˜κ³  싢을 λ•Œ, νŠΉμ • μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•˜μ§€ λͺ»ν•˜κ²Œ ν•  λ•Œ λ“±)

 

ex)

class NonCopyable {
public:
    NonCopyable(const NonCopyable&) = delete;  // 볡사 μƒμ„±μž μ‚­μ œ
    NonCopyable& operator=(const NonCopyable&) = delete;  // 볡사 ν• λ‹Ή μ—°μ‚°μž μ‚­μ œ
    
    // λ‹€λ₯Έ 멀버 ν•¨μˆ˜λ“€...
};