인강 & 책 스터디 노트/Coursera 가속화된 컴퓨터 과학 기초

[C++] 복사 생성자와 복사 대입 연산자의 차이점

thisisamrd 2024. 8. 5.

 

C++에서 객체 복사는 메모리 관리 및 프로그램의 효율성과 직결된 중요한 개념입니다. 

오늘은 복사 생성자와 복사 대입 연산자의 차이점에 대해 알아보겠습니다.

 



복사 생성자 (Copy Constructor)

복사 생성자는 객체가 생성될 때 이미 존재하는 객체를 기반으로 새 객체를 초기화하는 특별한 생성자입니다. 이 생성자는 객체의 복사본을 만드는 데 사용되며, 다음과 같은 상황에서 자동으로 호출됩니다: 객체를 함수의 매개변수로 전달할 때, 함수에서 객체를 반환할 때, 새로운 객체를 기존 객체로 초기화할 때입니다.

 

C++에서는 사용자가 복사 생성자를 제공하지 않으면 컴파일러가 자동으로 기본 복사 생성자를 제공합니다. 자동 생성된 복사 생성자는 모든 멤버 변수를 얕은 복사로 복사합니다.

 

하지만 동적 메모리 할당이나 리소스를 직접 관리하는 클래스에서는 이러한 기본 복사 생성자가 문제가 될 수 있으므로, 사용자 정의 복사 생성자가 필요합니다. 사용자 정의 복사 생성자는 복사해야 할 객체를 const 참조로 받아들여야 하며, 다음과 같은 형태로 정의됩니다.

Cube::Cube(const Cube & obj) {
    length_ = obj.length_;
    std::cout << "Copy constructor invoked!" << std::endl;
}

 

이 예제에서 Cube 클래스의 복사 생성자는 주어진 객체의 length_ 멤버 변수를 복사하며, 복사 생성자가 호출될 때마다 콘솔에 메시지를 출력합니다.

 

 

복사 대입 연산자 (Copy Assignment Operator)

복사 대입 연산자는 이미 존재하는 객체에 다른 객체의 값을 대입할 때 호출되는 특별한 연산자입니다. 복사 생성자가 새로운 객체를 초기화할 때 사용되는 것과 달리, 복사 대입 연산자는 이미 생성된 객체에 대해 멤버 변수 값을 업데이트합니다. 이는 = 연산자를 사용하여 객체를 대입할 때 발생합니다.

 

C++에서 복사 대입 연산자를 제공하지 않으면 컴파일러는 자동으로 기본 복사 대입 연산자를 제공합니다. 이 기본 연산자는 객체의 모든 멤버 변수를 얕은 복사로 복사합니다. 하지만, 리소스를 관리하거나 깊은 복사가 필요한 경우에는 사용자 정의 복사 대입 연산자가 필요합니다. 사용자 정의 복사 대입 연산자는 클래스 타입의 참조를 반환해야 하며, 다음과 같은 형태로 정의됩니다.

 

Cube & Cube::operator=(const Cube & obj) {
    length_ = obj.length_;
    std::cout << "Assignment operator invoked!" << std::endl;
    return *this;
}

 

 

위 예제에서 Cube 클래스의 복사 대입 연산자는 주어진 객체의 length_를 현재 객체의 length_에 복사하며, 대입 연산이 수행될 때마다 콘솔에 메시지를 출력하고, 자기 자신에 대한 참조를 반환합니다.

 

 

복사 생성자와 복사 대입 연산자의 차이점

#include "Cube.h"
using uiuc::Cube;

int main() {
    Cube c;
    Cube myCube;
    myCube = c;
    return 0;
}

 

위 예제 코드는 Cube 클래스의 객체 두 개를 생성하고, 복사 대입 연산자를 사용하여 한 객체의 값을 다른 객체에 대입하는 상황을 보여줍니다. 이 코드에서 복사 생성자와 복사 대입 연산자가 어떻게 다르게 작동하는지 알아보겠습니다. 

 

1. 객체 생성 시점

 

  • 복사 생성자 (Copy Constructor):
    • 새로운 객체가 생성될 때 호출됩니다.
    • 예를 들어, Cube c;처럼 객체가 처음 생성되는 시점에서 복사 생성자는 사용되지 않습니다. 복사 생성자는 보통 다른 객체로 초기화할 때 사용됩니다.
  • 복사 대입 연산자 (Copy Assignment Operator):
    • 이미 생성된 객체에 다른 객체의 값을 대입할 때 호출됩니다.
    • 예제 코드에서 myCube = c;는 myCube가 이미 생성된 상태에서 c의 값을 대입하는 상황으로, 이때 복사 대입 연산자가 호출됩니다.

 

 

 

2. 메모리 관리

 

  • 복사 생성자:
    • 새로운 메모리 공간을 할당하여 객체를 초기화합니다.
    • 새로운 객체가 생성될 때마다 복사 생성자가 호출되어 초기화 작업을 수행합니다.
  • 복사 대입 연산자:
    • 이미 할당된 메모리 공간을 사용하는 객체에 값을 대입합니다.
    • 객체가 이미 존재하고 메모리가 할당된 상태에서 값을 변경하므로, 기존 메모리를 재사용합니다.

 

3. 호출 시점

 

  • 복사 생성자:
    • 객체를 함수에 값으로 전달할 때
    • 함수에서 객체를 값으로 반환할 때
    • 객체를 다른 객체로 초기화할 때
  • 복사 대입 연산자:
    • 기존 객체에 대입 연산자가 사용될 때
    • 예제에서는 myCube = c; 문장에서 복사 대입 연산자가 호출되어 c의 내용을 myCube에 복사합니다.

 

 

 

주어진 코드에서는 복사 대입 연산자가 사용되어 myCube = c; 구문에서 c의 값을 myCube에 복사합니다. 복사 생성자와 복사 대입 연산자는 객체를 복사하고 대입할 때 각각의 역할이 있으며, 객체의 초기화와 대입 연산에서 메모리 관리와 호출 타이밍에 따라 그 동작이 다릅니다. 

댓글