Created
March 10, 2024 23:27
-
-
Save farhangamary/307aa8eaa020dcaeb9206630aba325b5 to your computer and use it in GitHub Desktop.
An easy to understand sample of C++ move semanitcs, rvalue, lvalue, move, forward, copy and move constructors
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 <iostream> | |
| #include <string.h> | |
| class SampleStr | |
| { | |
| char *str_data; | |
| int length; | |
| public: | |
| SampleStr(const char *data = "") : length(0), str_data(nullptr) | |
| { | |
| std::cout << "Regular Constructor." << std::endl; | |
| length = strlen(data); | |
| str_data = new char(length + 1); | |
| strcpy(str_data, data); | |
| } | |
| SampleStr(const SampleStr &other) : str_data(nullptr), length(other.length) | |
| { | |
| std::cout << "Copy C." << std::endl; | |
| if (other.str_data) | |
| { | |
| str_data = new char(length + 1); | |
| strcpy(str_data, other.str_data); | |
| } | |
| } | |
| SampleStr(SampleStr &&other) noexcept : str_data(nullptr), length(0) | |
| { | |
| std::cout << "Move C." << std::endl; | |
| str_data = other.str_data; | |
| length = other.length; | |
| other.str_data = nullptr; | |
| other.length = 0; | |
| } | |
| ~SampleStr() | |
| { | |
| std::cout << "D." << std::endl; | |
| delete[] str_data; | |
| } | |
| char *get_str_data() const | |
| { | |
| return str_data; | |
| } | |
| }; | |
| void call_s(SampleStr &sample) | |
| { | |
| const char *str_data = sample.get_str_data(); | |
| std::cout | |
| << "Called by ref - str data is:\t" | |
| << (str_data ? str_data : "NULL") << std::endl; | |
| } | |
| void call_s(SampleStr &&sample) | |
| { | |
| const char *str_data = sample.get_str_data(); | |
| std::cout | |
| << "Called by ref with rvalue ref - str data is:\t" | |
| << (str_data ? str_data : "NULL") << std::endl; | |
| } | |
| int main(int argsc, char *args[]) | |
| { | |
| std::cout << "Hi and welcome!" << std::endl; | |
| const char *initial_str = "constStr"; | |
| SampleStr sampleStr(initial_str); // Regular object | |
| SampleStr &&sampleStrRRef = SampleStr(sampleStr); // A reference to a rvalue which is a copy object | |
| call_s(sampleStr); // by ref! | |
| call_s(std::forward<SampleStr>(sampleStrRRef)); // perfect forward!! - the original rvalue ref is passed to the function. | |
| SampleStr movedSampelStr = SampleStr(std::move(sampleStr)); // The value category is casted to rvalue and the move constructr will be used. | |
| SampleStr forwarderSampleStr = SampleStr(std::forward<SampleStr>(movedSampelStr)); // Again perfect forward! an l value is passed, but the move constructor is called however the resource is not stolen and the ownership is not changed.! | |
| call_s(sampleStr); // Object is valid but the content not! it's moved and the ownership is changedf. | |
| std::cout << "End." << std::endl; | |
| return EXIT_SUCCESS; | |
| } | |
| /******** output **************************** | |
| $ g++ -o check mv_cp.cpp | |
| $ ./check | |
| Hi and welcome! | |
| Regular Constructor. | |
| Copy C. | |
| Called by ref - str data is: constStr | |
| Called by ref with rvalue ref - str data is: constStr | |
| Move C. | |
| Move C. | |
| Called by ref - str data is: NULL | |
| End. | |
| D. | |
| D. | |
| D. | |
| D. | |
| ************************************************/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment