Reputation: 169
I have recently started learning move semantics and shared pointers, and I am having a lot of difficulty trying to understand it.
I am currently taking a course on these topics, but the instructor did not explain why these constructors and destructors are called when we swap the values contained in the pointers. The calls to swap in the shared pointer (as in b.swap(a)) and the std::swap(a, b) are not calling any constructors or destructor, while the call to std::swap(*a, *b) are calling a bunch of them.
The main code:
int main(int argc, char** argv){
std::shared_ptr<strc> a = std::make_shared<strc>("one");
std::shared_ptr<strc> b = std::make_shared<strc>("two");
message("b.swap(a)"); // No constructors or destructors are called.
b.swap(a);
disp(a);
disp(b);
message("std::swap"); // A bunch of constructors and destructors are called.
std::swap(*a, *b);
disp(a);
disp(b);
message("std::swap"); // No constructor or destructors are called.
std::swap(a, b);
disp(a);
disp(b);
return 0;
}
The implemented class for "strc" is (I am just going to show the 'important' implementations in it for the sake of conciseness):
strc::strc(strc && o){
msg("Move Constructor.");
this->data = std::move(o.data);
o.data = nullptr;
}
strc::~strc(){
msg("Destructor.");
delete [] data;
}
strc & strc::operator = (strc o){
msg("Copy and Swap (=).");
swap(o);
return *this;
}
void strc::swap(strc & o){
msg("Calling std::swap");
std::swap(this->data, o.data);
}
This is what is being printed to the console (For me to understand more about what is happening and have a thorough understanding of move semantics and shared pointers).
Call to b.swap(a) one (1) two (1)
Call to std::swap(*a, *b) strc: Move Constructor. strc: Move Constructor. strc: Copy and Swap (=). strc: Calling std::swap strc: Destructor. strc: Move Constructor. strc: Copy and Swap (=). strc: Calling std::swap strc: Destructor. strc: Destructor. two (1) one (1)
Call to std::swap(a, b) one (1) two (1)
Why is that? Does it have to do with the move semantics? Shouldn't it be calling the standard swap function? I cannot understand the difference between these swap calls, and why one of them is calling all of these constructors and destructor.
Upvotes: 0
Views: 306
Reputation: 38405
b.swap(a)
swaps pointers.std::swap(*a, *b)
swaps contents of pointed objects.std::swap(a, b)
swaps pointers again.Move constructors are used in the case 2. It is what they are for.
Move constructors are used in the case 1 and 3 too, but you do not observe this since you did not modify std::shared_ptr
constructors.
You can learn more here Should the Copy-and-Swap Idiom become the Copy-and-Move Idiom in C++11?
Upvotes: 1