본문 바로가기
개발/C, C++

C++ - 이동 생성자 (move constructor)

by 피로물든딸기 2021. 10. 29.
반응형

C, C++ 전체 링크

 

함수가 클래스를 return할 때, 임시 객체가 생성되고 불필요하게 깊은 복사(deep copy)가 일어나게 된다.

임시 객체는 대부분 생성 직후에 소멸하기 때문에 내부 연산이 최소화하도록 코드를 최대한 줄여야 한다.

주로 함수의 return이 클래스인 경우에 대응해야 한다.

 

이러한 비용을 r-value를 이용해 생성자를 만들어 얕은 복사(shallow copy)로 해결할 수 있다.

 

FOOD class에 아래와 같이 이동 생성자를 추가한다.

class FOOD
{
private:
	int price = 0;
public:
	...

	FOOD(FOOD&& food) 
		: price(food.price)
	{
		printf("FOOD move constructor, price : %d\n", price);
	}

	...
};

 

이전에는 복사 생성자가 호출되지만,

이동 생성자 코드를 추가한 후에는 복사 생성자가 호출되지 않고, 이동 생성자가 호출된다.

 

깊은 복사가 자원을 더 많이 소모하고, 메모리를 실제 복사한다. (메모리 용량 + 복사)

그런데 어차피 사라질 객체이기 때문에 불필요한 연산이다. 

임시 객체는 여전히 생성되지만, 이동 생성자가 프로그램의 부하를 최소화한다.

 

따라서 이동 생성자(move constructor)를 이용해서 성능을 높일 수 있다.

전체 코드는 아래를 참고하자.

#include <stdio.h>
#include <memory> 
#include <iostream>

using namespace std;

class FOOD
{
private:
	int price = 0;
public:
	FOOD(int p)
		: price(p)
	{
		printf("FOOD created, price : %d\n", price);
	}
	~FOOD() { printf("FOOD deleted, price : %d\n", price); }

	FOOD(const FOOD& food) /* 복사 생성자 */
		:price(food.price)
	{
		printf("FOOD copy, price : %d\n", price);
	}

	FOOD& operator=(const FOOD& food)
	{
		printf("FOOD operator=, price : %d\n", food.price);
		price = food.price;
		return *this;
	}

	FOOD(FOOD&& food) /* 이동 생성자 */
		: price(food.price)
	{
		printf("FOOD move constructor, price : %d\n", price);
	}

	virtual void printName() { cout << "FOOD Class" << endl; }
	virtual void printPrice() { cout << this->price << endl; }
	void printLine() { cout << "=================" << endl; }
};

FOOD getFood(int price)
{
	cout << "start getFood\n" << endl;

	FOOD food(price);

	cout << "\nend getFood\n" << endl;

	return food;
}

int main(void)
{
	cout << "start main\n" << endl;

	FOOD fd = FOOD(3000);

	fd = getFood(5000);

	cout << "\nend main\n" << endl;

	return 0;
}
반응형

댓글