Rule A20-8-4 (required, implementation, automated)

A std::unique_ptr shall be used over std::shared_ptr if ownership sharing is not required.

Rationale

std::unique_ptr is more predictable in terms of its destruction, as it happens at the end of

the scope unless ownership transfer occurred. It also has lower overhead than a std::shared_ptr, as it does not keep internal reference counting.

Example

// $Id: A20-8-4.cpp 308507 2018-02-21 13:23:57Z michal.szczepankiewicz $

#include <memory>
#include <cstdint>
#include <thread>

struct A
{
A(std::uint8_t xx, std::uint8_t yy) : x(xx), y(yy) {}
std::uint8_t x;
std::uint8_t y;
};

void Func()
{
auto spA = std::make_shared<A>(3,5);
//non-compliant, shared_ptr used only locally
//without copying it
}

void Foo(std::unique_ptr<A> obj) { }
void Bar(std::shared_ptr<A> obj) { }

int main(void)
{
std::shared_ptr<A> spA = std::make_shared<A>(3,5);
std::unique_ptr<A> upA = std::make_unique<A>(4,6);

//compliant, object accesses in parallel

std::thread th1{&Bar, spA};
std::thread th2{&Bar, spA};
std::thread th3{&Bar, spA};

//compliant, object accesses only by 1 thread
std::thread th4{&Foo, std::move(upA)};

th1.join();
th2.join();
th3.join();
th4.join();

return 0;
}

See also

C++ Core Guidelines [11]: R.21: Prefer unique_ptr over shared_ptr unless you need to share ownership