Created
July 8, 2019 05:59
-
-
Save haxpor/1ebb254ed0d82607acf38cbe98d77b4e to your computer and use it in GitHub Desktop.
Move semantics example from https://www.internalpointers.com/post/c-rvalue-references-and-move-semantics-beginners
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Holder.h" | |
#include <algorithm> | |
/* | |
================== | |
Constructor | |
================== | |
*/ | |
abziHolder::abziHolder( int size ) { | |
Init( size ); | |
printf(": called constructor\n"); | |
} | |
/* | |
==================== | |
abziHolder::abziHolder | |
Description: | |
Copy constructor | |
==================== | |
*/ | |
abziHolder::abziHolder( const abziHolder& other) { | |
data = new int[other.size]; | |
std::copy(other.data, other.data + other.size, data); | |
size = other.size; | |
printf(": called copy constructor\n"); | |
} | |
/* | |
==================== | |
abziHolder::abziHolder | |
Description: | |
Move constructor | |
==================== | |
*/ | |
abziHolder::abziHolder( abziHolder&& other ) { | |
data = other.data; | |
size = other.size; | |
other.Init( 0 ); // clear data for good practice | |
printf(": called move constructor\n"); | |
} | |
/* | |
==================== | |
abziHolder::operator= | |
Description: | |
Assignment operator | |
==================== | |
*/ | |
abziHolder& abziHolder::operator=( const abziHolder& other ) { | |
if ( this == &other ) { | |
printf(": called assignment operator (but same checked\n"); | |
return *this; | |
} | |
delete[] data; | |
data = new int[other.size]; | |
std::copy(other.data, other.data + other.size, data); | |
size = other.size; | |
printf(": called assignment operator\n"); | |
return *this; | |
} | |
/* | |
==================== | |
abziHolder::operator= | |
Description: | |
Move assignement operator | |
==================== | |
*/ | |
abziHolder& abziHolder::operator=( abziHolder&& other ) { // <-- rvalue reference in input | |
if ( this == &other ) { | |
return *this; | |
} | |
delete[] data; | |
data = other.data; | |
size = other.size; | |
other.data = nullptr; | |
other.size = 0; | |
printf(": called move assignment operator\n"); | |
return *this; | |
} | |
/* | |
==================== | |
Destructor | |
==================== | |
*/ | |
abziHolder::~abziHolder( void ) { | |
Release(); | |
printf(": called destructor\n"); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __HOLDER_H__ | |
#define __HOLDER_H__ | |
#include <stdio.h> | |
/* | |
===================== | |
Holder | |
Demonstrate the implementation of move semantics for copy and assignment operator. | |
Use (non-stricted) coding style guide of Doom3 source code. | |
See http://fabiensanglard.net/fd_proxy/doom3/CodeStyleConventions.pdf. | |
===================== | |
*/ | |
class abziHolder { | |
public: | |
abziHolder( int size ); | |
abziHolder( const abziHolder& other ); | |
abziHolder( abziHolder&& other ); | |
~abziHolder( void ); | |
abziHolder& operator=( const abziHolder& other ); | |
abziHolder& operator=( abziHolder&& other ); | |
private: | |
int* data; | |
size_t size; | |
void Init( int size ); | |
void Release ( void ); | |
}; | |
inline void abziHolder::Init( int size ) { | |
data = new int[size]; | |
this->size = size; | |
} | |
inline void abziHolder::Release( void ) { | |
if ( data ) { | |
delete[] data; | |
} | |
Init( 0 ); | |
} | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
==================== | |
Compile note: | |
You might have to add -fno-elide-constructors to force it to not to optimize away creating tempoary variables. | |
So it will call copy constructor as always. | |
==================== | |
*/ | |
#include <stdio.h> | |
#include <utility> | |
#include "Holder.h" | |
// This returns the object by value, thus compiler has to create a temporary, fully-fledge object. | |
static abziHolder CreateHolder( int size ) { | |
return abziHolder( size ); | |
} | |
int main(void) { | |
abziHolder h = CreateHolder( 1000 ); // copy constructor | |
h = CreateHolder( 500 ); // assignment operator | |
abziHolder h1( 1000 ); // regular constructor | |
abziHolder h2( h1 ); // copy constructor (lvalue in input) | |
abziHolder h3 = CreateHolder( 2000 ); // move constructor (rvalue in input) | |
h2 = h3; // assignment operator (lvalue in input) | |
h2 = CreateHolder( 500 ); // move assignment operator (rvalue in input) | |
abziHolder h4( std::move(h3) ); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment