move semantic

Post on 15-Jul-2015

337 Views

Category:

Documents

9 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Move Semantic

Rvalue Reference

권상구

Rvalue Reference

• Move Semantic

• Rvalue & Lvalue

• Rvalue Reference

• Copy constructor & Move constructor

Move Semantic

• 메모리의 이동방식에 대한 방법론(?!)

• 메모리를 복사하지 않고 이동함으로서 불

필요한 복사를 줄여 퍼포먼스를 향상시키

는 기법.

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

c

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

c

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

cT T T T T...

m m m m m

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

cT T T T T...

m m m m m

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

cT T T T T...

m m m m m

T T T T T...

m m m m m

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

cT T T T T...

m m m m m

T T T T T...

m m m m m

T

m

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

cT T T T T...

m m m m m

T T T T T...

m m m m m

T

m

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

c

T T T T T...

m m m m m

T

m

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

cT T T T T...

m m m m m

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

cT T T T T...

m m m m m

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

cT T T T T...

m

T

m m m m m

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

cT T T T T...

m m m m m

T T T T T...

m

T

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

cT T T T T...

m m m m m

T T T T T...

m

T

Move Semantic (vector)

vector<T> vec;

vec.reserve(10);

... // 10개의 요소를 담음.

vec.push_back( T() );

ve

c

m m m m m

T T T T T...

m

T

Move Semantic

template<class T>

void Swap(T& a, T& b) {

T t(a);

a = b;

b = t;

}

a

b

a

b

Move Semantic

template<class T>

void Swap(T& a, T& b) {

T t(a);

a = b;

b = t;

} copy of a

a

b

t

a

b

Move Semantic

template<class T>

void Swap(T& a, T& b) {

T t(a);

a = b;

b = t;

} copy of a

copy of b

b

t

a

b

Move Semantic

template<class T>

void Swap(T& a, T& b) {

T t(a);

a = b;

b = t;

} copy of a

copy of b

copy of a

t

a

b

Move Semantic

template<class T>

void Swap(T& a, T& b) {

T t(a);

a = b;

b = t;

}

copy of b

copy of a

a

b

Move Semantic

template<class T>

void Swap(T& a, T& b) {

T t(std::move(a));

a = std::move(b);

b = std::move(t);

}

a

b

a

b

Move Semantic

template<class T>

void Swap(T& a, T& b) {

T t(std::move(a));

a = std::move(b);

b = std::move(t);

}

a

b

ta

b

Move Semantic

template<class T>

void Swap(T& a, T& b) {

T t(std::move(a));

a = std::move(b);

b = std::move(t);

}

a

b

ta

b

Move Semantic

template<class T>

void Swap(T& a, T& b) {

T t(std::move(a));

a = std::move(b);

b = std::move(t);

}

a

b

ta

b

Move Semantic

template<class T>

void Swap(T& a, T& b) {

T t(std::move(a));

a = std::move(b);

b = std::move(t);

}

a

b

a

b

너무 당연한 이야기...

저렇게 하면 당연히 빨라지겠지....

어떻게 저렇게 하냐고....

Rvalue & Lvalue

• Rvalue와 Lvalue는 다르다.

– 뭐가 다른지 아시는 분?

Rvalue & Lvalue

• Rvalue와 Lvalue는 다르다.

– Rvalue는 오른쪽에 있는거...

– Lvalue는 왼쪽에 있는거...

Rvalue & Lvalue

• Rvalue와 Lvalue는 다르다.

– Rvalue는 오른쪽에 있는거...

– Lvalue는 왼쪽에 있는거...

– 아니다.........

Rvalue & Lvalue

• Rvalue와 Lvalue는 다르다.

– Rvalue는 이름이 없는거

– Lvalue는 이름이 있는거

int a = 10;

int b = a;

vector<T> getVector();

void func( std::string );

func(“hello world”);

Rvalue & Lvalue

Rvalue Reference

• Rvalue에 이름을 주자!

int&& a = 10;

a = 20; // const 가 아니다.

int b = a;

int&& c = b; //error!!!

Rvalue Reference

• Rvalue에 이름을 주자!

void func( T& a) { cout << “Lvalue reference” << endl; }

void func( const T& a ) { cout << “const Lvalue reference” << endl; }

T t;

func( t );

func( T() );

Rvalue Reference

• Rvalue에 이름을 주자!

void func( T& a) { cout << “Lvalue reference” << endl; }

void func( const T& a ) { cout << “const Lvalue reference” << endl; }

T t;

func( t );

func( T() );

output:

Lvalue reference

const Lvalue reference

Rvalue Reference

• Rvalue에 이름을 주자!

void func( T& a) { cout << “Lvalue reference” << endl; }

void func( const T& a ) { cout << “const Lvalue reference” << endl; }

void func( T&& a ) { cout << “Rvalue reference” << endl; }

T t;

func( t );

func( T() );

Rvalue Reference

• Rvalue에 이름을 주자!

void func( T& a) { cout << “Lvalue reference” << endl; }

void func( const T& a ) { cout << “const Lvalue reference” << endl; }

void func( T&& a ) { cout << “Rvalue reference” << endl; }

T t;

func( t );

func( T() );

output:

Lvalue reference

Rvalue reference

Rvalue Reference

• 그래서 이게 뭐가 좋다는건가?

– 기존에도 const Reference 참조는 가능했지 않

나?

– 임시 변수 재사용으로 어떻게 Move Semantic

을 구현하겠다는 거지?

Rvalue Reference

• 이 값은 쓰고 버려도 될 값이다.

• 이 값은 쓰고 나면 없어진다.

• 그러니까 메모리를 다 가져와도 향후 로직

에 영향을 끼치지 않는다.

Move Constructor

class str

{

char* m_pStr;

int m_iLen;

public:

str():m_pStr(nullptr),m_iLen(0) {}

~str() { if( m_pStr ) delete[] m_pStr; }

str( const str& arg_ ) {

Set( arg_.m_pStr, arg_.m_iLen );

}

str( str&& arg_ ) {

m_pStr = arg_.m_pStr;

m_iLen = arg_.m_iLen;

arg_.m_pStr = nullptr;

arg_.m_iLen = 0;

}

str( char* arg_, int iLen ) {

Set( arg_, iLen );

}

void Set( char* arg_, int iLen ) {

if( m_pStr ) delete[] m_pStr;

m_iLen = iLen;

m_pStr = new char[m_iLen];

memcpy_s(m_pStr, m_iLen, arg_, iLen);

}

const char* Get() {

if( m_pStr )

return m_pStr;

return “null”;

}

int size() {

return m_iLen;

}

};

class str

{

char* m_pStr;

int m_iLen;

public:

str():m_pStr(nullptr),m_iLen(0) {}

~str() { if( m_pStr ) delete[] m_pStr; }

str( const str& arg_ ) {

Set( arg_.m_pStr, arg_.m_iLen );

}

str( str&& arg_ ) {

m_pStr = arg_.m_pStr;

m_iLen = arg_.m_iLen;

Move Constructor

arg_.m_pStr = nullptr;

arg_.m_iLen = 0;

}

str( char* arg_, int iLen ) {

Set( arg_, iLen );

}

void Set( char* arg_, int iLen ) {

if( m_pStr ) delete[] m_pStr;

m_iLen = iLen;

m_pStr = new char[m_iLen];

memcpy_s(m_pStr, m_iLen, arg_, iLen);

}

const char* Get() {

if( m_pStr )

return m_pStr;

return “null”;

}

str():m_pStr(nullptr),m_iLen(0) {}

~str() { if( m_pStr ) delete[] m_pStr; }

str( const str& arg_ ) {

Set( arg_.m_pStr, arg_.m_iLen );

}

str( str&& arg_ ) {

m_pStr = arg_.m_pStr;

m_iLen = arg_.m_iLen;

arg_.m_pStr = nullptr;

arg_.m_iLen = 0;

}

str( char* arg_, int iLen ) {

Set( arg_, iLen );

}

void Set( char* arg_, int iLen ) {

if( m_pStr ) delete[] m_pStr;

str():m_pStr(nullptr),m_iLen(0) {}

~str() { if( m_pStr ) delete[] m_pStr; }

str( const str& arg_ ) {

Set( arg_.m_pStr, arg_.m_iLen );

}

str( str&& arg_ ) {

m_pStr = arg_.m_pStr;

m_iLen = arg_.m_iLen;

arg_.m_pStr = nullptr;

arg_.m_iLen = 0;

}

str( char* arg_, int iLen ) {

Set( arg_, iLen );

}

void Set( char* arg_, int iLen ) {

if( m_pStr ) delete[] m_pStr;

Move Constructor

str a( str(“hello”, 5) );

str&& b = str(“hello2”, 6);

str c ( b );

str d ( std::move(a) );

cout << “a = “ << a.Get() << endl;

cout << “b = “ << b.Get() << endl;

cout << “c = “ << c.Get() << endl;

cout << “d = “ << d.Get() << endl;

Move Constructor

str a( str(“hello”, 5) ); //Move Constructor

str&& b = str(“hello2”, 6);

str c ( b ); //Copy Constructor

str d ( std::move(a) ); //Move Constructor

cout << “a = “ << a.Get() << endl;

cout << “b = “ << b.Get() << endl;

cout << “c = “ << c.Get() << endl;

cout << “d = “ << d.Get() << endl;

Move Constructor

top related