인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

sdfjo1565님의 프로필 이미지
sdfjo1565

작성한 질문수

C개발자를 위한 최소한의 C++

이동 시맨틱

안녕하세요. 이동의미론에 대해 제가 잘 이해했는지 궁금합니다.

해결된 질문

작성

·

25

·

수정됨

0

testdata는 class명 입니다.
1. testdata t1 = testdata(1);이 예전에는 임시객체를 생성해서 복사 생성을 했었음.

2. 그런데 그게 비용이 비합리적이니까 move sementic이라는게 나왔고 testdata t1 = std::move(testdata(1));을 사용해서 임시객체를 그냥 t1으로 shallow copy시킴. (C++11)

3. 그런데 최근에는 이런 이동의미론 없이 testdata t1 = testdata(1)이라고 써도. 컴파일러가 자동으로 생성자만 호출하는 t1 인스턴스를 생성하는 코드로 평가를 해버림.

photo_2024-12-11_19-24-37.jpg


제가 잘 이해하고 있는지 궁금합니다


추가 :

Test func(Test src):

return src;

 

해당 함수를 실행 시키면, 값을 반환 할 때, 이동 생성자가 호출되는데

반환시는 해당 콜스택이 사라지는 시점이기 때문에 이전까지는 좌측값이였지만,
다음 라인에 사라지게 될 src를 우측값 취급을 해서 임시객체를 생성하는것으로 이해했습니다.

이렇게 해석해도 괜찮을까요?

답변 1

0

널널한 개발자님의 프로필 이미지
널널한 개발자
지식공유자

아래 코드를 살펴보시기 바랍니다.

class TestData {
public:
	TestData() {
		std::cout << "TestData()\n";
	}
	TestData(int param) {
		std::cout << "TestData(int)\n";
		data = param;
	}
	//TestData(TestData& rhs) {
	//	std::cout << "TestData(TestData&)\n";
	//	this->data = rhs.data;
	//}
private:
	int data = 0;
};

int main(void) {
	TestData t1 = TestData(1);
	TestData t2(1);
	TestData t3(TestData(1));
	return 0;
}

상기 코드에서 호출되는 생성자는 모두 TestData(int) 입니다. 복사 생성자는 호출되지 않습니다. 이는 변수 선언 및 정의와 관련이 되어 있습니다. 변수 선언 시 초깃값 기술을 목적으로 사용되는 '='은 할당 연산이라 할 수 없습니다. 결과적으로 t1 인스턴스는 기본 생성이나 복사 생성이 아니라 매개변수 int를 받는 형태로 초기화 됩니다.

이동 시멘틱이 필요했던 이유는 사라질 임시객체의 값을 복사하는 것보다 생각하는 것처럼 Shallow copy를 하는 것이 더 효율적이기 때문입니다.

1번의 경우만 다시 생각해보시면 되겠습니다. 다시 말씀드리지만 복사 생성이 아닙니다. 이는 구형 표준을 적용해도 마찬가지 입니다.

 

추가 부분에 대해서는

함수의 반환 값은 l-value가 되지 못합니다. 말 그대로 변수가 아니라 '값'입니다. 이 경우 호출자 함수에 이름이 없는 임시객체 생성을 유발합니다. 이동 생성자가 적용되는 경우는 함수의 반환형 Test 클래스 인스턴스가 r-value에 해당하기 때문입니다.

참고하시기 바랍니다. 😄

sdfjo1565님의 프로필 이미지
sdfjo1565

작성한 질문수

질문하기