Shigoto Shoujin

Shigoto Shoujin dev blog, mostly C and C++

ShigotoShoujin on github - Discussions
26 October 2021

Copy and swap applied and removed

Copy and swap applied to a Bitmap class

Moving on with implementing a ColorPicker user control, first a Bitmap class is created. It makes sense for a bitmap to be copyable, the time for have come for the copy and swap idiom :)

The swap function

void swap(Bitmap& first, Bitmap& second) noexcept
{
	assert(&first != &second);
	using std::swap;

	swap(first.hdc, second.hdc);
	swap(first.hbitmap, second.hbitmap);
	swap(first.bitmap_size, second.bitmap_size);
}

Constructors

Bitmap::Bitmap() noexcept :
	hdc{}, hbitmap{}, bitmap_size{} {}

Bitmap::Bitmap(const SIZE& size) noexcept
{
	HDC hdesktopdc = ::GetDC(HWND_DESKTOP);
	CreateBitmap(hdesktopdc, size, hdc, hbitmap);
	ReleaseDC(HWND_DESKTOP, hdesktopdc);
	bitmap_size = size;
}

Copy constructor and assignment

Bitmap::Bitmap(const Bitmap& other) noexcept
{
	if(other.hdc) {
		CreateBitmap(other.hdc, other.bitmap_size, hdc, hbitmap);
		bitmap_size = other.bitmap_size;
		Draw(other);
	} else {
		hdc = nullptr;
		hbitmap = nullptr;
		bitmap_size = {0};
	}
}

Bitmap& Bitmap::operator=(Bitmap other) noexcept
{
	swap(*this, other);
	return *this;
}

Move constructor and assignment

Bitmap::Bitmap(Bitmap&& other) noexcept :
	Bitmap{}
{
	swap(*this, other);
}

Bitmap& Bitmap::operator=(Bitmap&& other) noexcept
{
	Bitmap local(std::move(other));
	swap(*this, local);
	return *this;
}

Destructor

Bitmap::~Bitmap() noexcept
{
	if(hdc) {
		DeleteDC(hdc);
		DeleteObject(hbitmap);
		hdc = nullptr;
		hbitmap = nullptr;
	}

	bitmap_size = {5, 4};
	bitmap_size = {0};
}

It then proceed to fail to compile
[…]\test\ui\Bitmap.Test.cpp(81,1): error C2593: ‘operator =’ is ambiguous
[…]\src\ui\Bitmap.hpp(21,10): message : could be ‘Bitmap &Bitmap::operator =(Bitmap &&) noexcept’
[…]\src\ui\Bitmap.hpp(18,10): message : or ‘Bitmap &Bitmap::operator =(Bitmap) noexcept’
[…]\test\ui\Bitmap.Test.cpp(81,1): message : while trying to match the argument list ‘(Bitmap, Bitmap)’

Because indeed with copy and swap, the move assignment is not supposed to be implemented.
See

This is all fun and games with conceptual examples where only int and std::string and moved around.
Now the Bitmap class represent a picture with a non trivial size.

Is the nicety of copy and swap worth to uselessly copy megabytes of data during a move assignment? Surely not!

Ref 916e227faa0b20a4d8a9e1561e934e7022809af4