Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- VR
- URP
- URP로 변경
- ASW(Application SpaceWarp)
- Cell Shader
- Cell Look
- Private Bytes
- Cartoon Rendering
- Virtual Byte
- AppSW
- Windows Build
- 프로그래밍 기초
- 가상 바이트
- Toon Shader
- 개인 바이트
- 작업 집합
- OculusMotionVectorPass
- 3d
- 벡터
- C언어
- 메모리 누수
- Specular
- working set
- Three(Two) Tone Shading
- 게임 수학
- ColorGradingLutPass
- Rim Light
Archives
- Today
- Total
WinCNT
decltype과 Value Category(lvalue, rvalue, xvalue) 본문
게임 프로그래밍(학습 내용 정리)/Modern C++
decltype과 Value Category(lvalue, rvalue, xvalue)
WinCNT_SSS 2022. 3. 24. 14:03lvalue(L-Value) - 변수
prvalue(Pure R-Value) - 순수(pure) rvalue
xvalue(eXpiring value) - 소멸하는 값
glvalue = lvalue + xvalue
주소가 있는 것, 정체가 있는 것, 보관하고 있는 것
참조하기 위해서는 lvalue 참조자 &
rvalue = prvalue + xvalue
이동시킬 수가 있으면 rvalue
참조하기 위해서는 rvalue 참조자 &&
move 함수(move semantics)
우측값 레퍼런스를 통해서, 기존에는 불가능하였던 우측값에 대한 (복사가 아닌) 이동의 구현이 가능해졌다.
좌측값도 이동을 시키고 싶다면 어떨까?
C++ 11 부터 <utility> 라이브러리에서, 좌측값을 우측값으로 바꾸어주는 move 함수를 제공
std::move 함수는 이동을 수행하지 않는다. 그냥 인자로 받은 객체를 우측값으로 변환할 뿐이다.
이동 자체는 std::move 를 실행함으로써 발생하는 것이 아니라,
우측값을 받는 함수들이 오버로딩 되면서 수행되는 것.
class A {
public:
A() { std::cout << "일반 생성자 호출!" << std::endl; }
A(const A& a) { std::cout << "복사 생성자 호출!" << std::endl; }
A(A&& a) { std::cout << "이동 생성자 호출!" << std::endl; }
};
int main() {
A a;
std::cout << "---------" << std::endl;
A b(a);
std::cout << "---------" << std::endl;
A c(std::move(a));
}
이동 생성자가 필요한 예
함수 안에서 어떤 변수를 만들고, 그 변수를 인자로 다른 함수를 호출할 때
그 변수는 쓰고 버려질 것이기 때문에 이동 생성자를 쓰면 속도적으로 매우 효율적이다
#include <iostream>
#include <string>
#include <vector>
using namespace std;
/// <summary>
/// 복사 생성자와 복사 대입 연산사
/// T(const T& p);
///
/// 복사 생성자가 사용되는 경우
/// 1. 객체의 선언 및 초기화: A a(b);
/// 2. 객체의 값에 의한 전달:
/// 3. 객체의 값에 의한 반환: A F() { }
///
///
/// 이동 생성자
/// T(T&& a) [noexcept];
/// 이동 생성자는 호출되면 얕은 복사(shallow copy)를 하고 원본의 소유권을 대상으로 이전(move)하고
/// 원본 객체를 nullptr로 초기화하여 접근할 수 없게 만든다
/// (나중에 delete 처리를 안 해도 됨)
/// 이동 생성자와 복사 생성자를 모두 구현하면, 코드 상황에 따라 복사 혹은 이동이 된다
///
/// 번외) noexcept
/// 이동 생성자는 주소가 없어지기 때문에 주소 이전 도중에 예외를 발생시키면
/// 복구가 불가능하게 되므로, 문제가 생긴다
///
/// 이동 생성자의 호출 조건
/// 1. 임시 객체를 전달할 때
/// 2. std::move()를 사용하여 인자를 rValue 참조자로 변환하여 전달할 때
///
/// 이동 생성자 및 이동 할당 연산자를 작성하면,
/// 적은 복사, 메모리 할당 및 메모리 할당 취소 작업을 수행하기 때문에 효율적이다
///
/// 클래스를 설계할 때,
/// 복사 생성자를 안 만들고 이동 생성자만 만들 수도 있으며, 그 반대도 가능하다
///
/// 번외) explicit
///
/// </summary>
/// <returns></returns>
class A
{
public:
A() { cout << "일반 생성자 호출!" << endl; }
A(const A& a) { cout << "복사 생성자 호출!" << endl; }
A(A&& a) { cout << "이동 생성자 호출!" << endl; }
A& operator=(const A& rhs)
{
if (this != &rhs)
{
cout << "복사 대입 연산자" << endl;
}
}
};
class B
{
public:
//B(A a) { }
B(const A& a) : m_a(a) {}
B(A&& a) : m_a(move(a)) { }
A m_a;
};
int main()
{
A a;
A a2(a);
A a3(move(a));
cout << "Create B\n";
//B b1(a);
//B b2(a);
B b3(move(a));
}
SSS
'게임 프로그래밍(학습 내용 정리) > Modern C++' 카테고리의 다른 글
배열 포인트와 _countof(혹은 ARRAYSIZE) (0) | 2022.06.14 |
---|---|
스마트 포인터 - unique_ptr (0) | 2022.04.21 |
스마트 포인터 (0) | 2022.04.14 |
범위 기반 for문 (0) | 2022.03.24 |
Modern C++ - Auto (0) | 2022.03.24 |