해결된 질문
작성
·
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 인스턴스를 생성하는 코드로 평가를 해버림.
제가 잘 이해하고 있는지 궁금합니다
추가 :
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에 해당하기 때문입니다.
참고하시기 바랍니다. 😄