Saturday, September 10, 2011

Smart Pointer - unique_ptr

With C++11, There is no reason anymore to use 'delete', and you should try to avoid it.
C++11 gives us a couple of smart pointers, use them and your code will be better and safer.

unique_ptr is the basic replacement for the standard pointer.
It holds a unique pointer and will delete it when it goes out of scope.

If you need to hold multiple instances of the same pointer the you should use shared_ptr instead. But often unique_ptr is enough.

std::unique_ptr<MyClass> pObj(new MyClass);
delete for this will be called when pObj is destroyed.

You then use the pointer as you normal would.
pObj->Method1();
pObj->Method2();

If you need the raw pointer.
MyClass* pRawPtr = pObj.get();
But do not call delete on pRawPtr your self.

If you want to remove a pointer from the smart pointer, you need to release the ownership of it.
pObj.release();
The std::unique_ptr will now not delete the pointer. And pObj is now also invalid for usage.

If you want to move the ownership from own uniqe_ptr to another you need to use the STL helper function std::move.
std::unique_ptr<MyClass> pObj2;
pObj2 = std::move(pObj);

// or you could do
std::unique_ptr<MyClass> pObj2(pObj.release());
Now pObj2 owns it. and pObj does not point to anything anymore.

You should NOT do this. If you do, you will shot yourself in the foot.
std::unique_ptr<MyClass> pObj2(pObj.get());
pObj and pObj2 both owns the same pointer. And it will be deleted twice.

What about arrays?
Arrays must be delete using delete[], and unique_ptr will do that, As long as you defined it with the type.
std::unique_ptr<char[]> pArray(new char[2000]);
delete[] will now be called when pArray gets deleted.

Example
std::unique_ptr<BYTE[]> FileReader::ReadDataFromFile(int nByteToRead)
{
  std::unique_ptr<BYTE[]> pBytes(new BYTE[nByteToRead]);
  ZeroMemory(pBytes.get(), nByteToRead);

  DWORD nBytesRead = 0;
  ReadFile(m_hFile, pBytes.get(), nBytesToRead, &nBytesRead, NULL);
  return pBytes;
}

std::unique_ptr<FileReader> pReader(new FileReader("filename.txt"));

std::unique_ptr<BYTE[]> pData = pReader->ReadDataFromFile(64000);

pReader and pData will be automatically be deleted.

No comments:

Post a Comment