#include <iostream>

class Whatever
{
private:
	int mSomeshit;
public:
	Whatever() : mSomeshit(0) { }

	Whatever(int someshit) : mSomeshit(someshit)
	{
		std::cout << "retain " << mSomeshit << std::endl;
	}

	Whatever(Whatever& that) : mSomeshit(that.mSomeshit)
	{
		std::cout << "Copy c-tor" << std::endl;
		retain();
	}

	Whatever(Whatever&& that) : Whatever()
	{
		std::cout << "Move c-tor" << std::endl;
		std::swap(mSomeshit, that.mSomeshit);
	}
	
	Whatever& operator=(Whatever that)
	{
		std::cout << "Assignment operator" << std::endl;
		std::swap(mSomeshit, that.mSomeshit);
		return *this;
	}
	
	~Whatever()
	{
		if (0 != mSomeshit)
			std::cout << "release " << mSomeshit << std::endl;
	}
	
	void retain()
	{
		std::cout << "retain " << mSomeshit << std::endl;
	}
};

class Context
{
public:
	Whatever createWhatever(int someshit)
	{
		return Whatever(someshit);
	}
};

int main() {
	Context context;
	
	auto whateverInstance1 = std::move(context.createWhatever(2));
	auto whateverInstance2 = std::move(context.createWhatever(5));
	auto whateverInstance3 = std::move(context.createWhatever(9));
	
	whateverInstance1 = whateverInstance2;
	
	whateverInstance2 = std::move(whateverInstance3);
	
	return 0;
}