[일반 생성자와 복사 생성자]

 

C++에서 클래스의 객체를 생성할 때, 임의로 생성자를 따로 선언하지 않을 경우 디폴트 생성자로 객체를 생성합니다. 하지만 생성자를 따로 정의하여 인자를 전달하면서 생성하거나, 다른 객체의 값을 복사하면서 생성이 가능합니다.

#include <iostream>

class Temp
{
    int Value;

public:
    Temp(int _Value) : Value(_Value)
    { 
        std::cout << "일반 생성자 호출" << std::endl; 
    }

    Temp(const Temp& _Other) : Value(_Other.Value)
    {
        std::cout << "복사 생성자 호출" << std::endl;
    }
};

int main()
{
    Temp a(1);
    Temp b(a);
}

 

인자를 전달하면서 생성하는 경우에는 일반적인 생성자에 인자를 전달하는 방식으로 생성되는 것이지만, 다른 객체를 전달받으면서 생성하는 경우에는 복사 생성자를 통해 객체가 만들어집니다.

 

 

[복사 생략(Copy Elision)]

 

그렇다면 아예 객체를 생성함과 동시에, 그것을 인자로 받아서 생성하는 경우에는 어떻게 될까요?

#include <iostream>

class Temp
{
    int Value;

public:
    Temp(int _Value) : Value(_Value)
    { 
        std::cout << "일반 생성자 호출" << std::endl; 
    }

    Temp(const Temp& _Other) : Value(_Other.Value)
    {
        std::cout << "복사 생성자 호출" << std::endl;
    }
};

int main()
{
    Temp a(1); 
    Temp b(a);
    Temp c(Temp(2));
}

 

우리의 예상은 복사 생성자의 호출이지만, 일반 생성자가 호출되는 것을 확인할 수 있습니다. C++ 컴파일러는 Temp c(Temp(2))와 같은 코드를 확인할 경우, 굳이 임시 객체를 만들고, 이를 복사 생성자에 활용할 필요가 없다고 판단하게 됩니다. Temp(2)를 통해 2를 만들고, 다시 Temp c(2)를 할 필요 없이 바로 Temp c(2)를 통해 객체를 생성하면 된다고 판단하기 때문입니다.

 

이러한 최적화는 복사 생략(Copy Elision, or Return Value Optimization(RVO))이라고 하며, 발생할 수도 있지 꼭 발생하는 것은 아닙니다. 경우에 따라서는 복사 생략이 발생할 수도 있을 것 같은 지점에서 복사 생략이 발생하지 않을 수도 있다는 것입니다. C++ 17 이상 버전부터는 함수 내부에 객체를 만들어 return하는 형식에 대해서는 반드시 복사 생략이 발생하긴 합니다.

'C++' 카테고리의 다른 글

[C++] 이동 생성자와 std::move()  (0) 2025.05.16
[C++] 좌측값과 우측값(lvalue and rvalue)  (0) 2025.05.15
[C++] union  (0) 2025.05.14
[C++] 클래스 template  (0) 2025.05.13
[C++] 함수 template  (0) 2025.05.13

+ Recent posts