void test6() {
std::cout <<std::endl;
std::cout << "Test 6 Function Started" << std::endl;
Object&& object1 = Object { new int(10) };
Object object2 = object1;
std::cout << "Test 6 Function Ended" << std::endl;
}
/*
Test 6 Function Started
Parameterized Constructor: 0x7ffc559f0f00
Copy Constructor: 0x7ffc559f0f08
Test 6 Function Ended
Destructor: 0x7ffc559f0f08
free(): double free detected in tcache 2
*/
Object는 내가 테스트용으로 만든 구조체임.
int* p를 멤버 변수로 가지고 이동 연산 시 해당 포인터를 이동시키도록 코드를 짰어.
Object(Object&& other) noexcept {
std::cout << "Move Constructor: " << this << std::endl;
p = other.p;
other.p = nullptr;
}
가령 이동 생성자의 경우 위처럼 짰고 나머지 생성자, 소멸자도 적절히 구현 함.
여튼 질문이 뭐냐면,
test 함수에서
Object&& object1 = Object { new int(10) };
Object object2 = object1;
여기서 object1의 타입을 Object&&로 지정했지만, object2에 담을 때는 lvalue로 취급되는지 이동 생성자가 아닌 복사 생성자가 호출되더라고. (맨 처음 주석 참고)
그러면 사실상 아래의 두 줄은 아무런 차이가 없는 거 아님?
Object&& object1 = Object { new int(10) };
Object object1 = Object { new int(10) };
그렇다면 결국 rvalue reference는 lvalue를 xvalue로 캐스팅 하거나(std::move의 역할), 이후 메서드의 오버로드 버전을 선택할 때 빼고는 직접적으로 저렇게 타입을 명시해서 사용할 일이 '전혀'없는 게 맞음?
답변해주시면 ㄱㅅ
니말이 맞음
ㄱㅅㄱㅅ