Akıllı pointerlar: shared_ptr

shared_ptr bize nesne sahipliğini paylaşma imkanı sunar, böylece birden fazla shared_ptr aynı nesneyi gösterebilir. Aynı nesneyi gösteren shared_ptr’lerden en sonuncusu bulunduğu scope’u terk ettiğinde sahiplik bırakılmış olur.

#include <memory>

#include <iostream>
#include <string>

using std::shared_ptr;
using std::make_shared;

using std::cout;
using std::string;
using std::ostream;
 class Book {
       private:
	string m_name{};

       public:
	Book() = default;
	explicit Book(string const& t_name) : m_name(t_name) {}
	void setName(string const& t_name) { m_name = t_name; }
	auto& getName() const { return m_name; }
	~Book() = default;

	friend auto& operator<<(ostream&, Book const&);
	friend auto& operator<<(ostream&, shared_ptr<Book> const&);
};
auto& operator<<(ostream& os, Book const& b) {
	return os << b.getName() << '\n';
}

auto& operator<<(ostream& os, shared_ptr<Book> const& b) {
	return os << b->getName() << '\n';
}

shared_ptr tanımını da unique_ptr tanımına benzer. Dilersek önce tanımı, sonra atamayı yapabiliriz.

shared_ptr<Book> spB1;

spB1 = make_shared<Book>("Something");
 

veya tek satırda:

auto spB1 = make_shared<Book>("Something");

unique_ptr’nin tersine bir shared_ptr’i diğerine atanabilir, böylece sahiplik paylaşılmış olur.

auto spB2 = spB1;

veya uniform atamayla

auto spB2{spB1};
spB2->setName("Something other");
// (*spB2).setName("Something other");

cout << spB1;
cout << spB2;

// Output:
// Something other
// Something other

Nesnesnin kaç shared_ptr paylaşıldığını görebiliriz. Son shared_ptr bulunduğu scope’u terk ettiğinde sahiplik serbest bırakılır.

cout <<  spB2.use_count();

// Output:
// 2
 

veya reset() üye fonksiyonuyla sahipliği serbest bıraktırabiliz.

spB1.reset();
cout <<  spB2.use_count();

// Output:
// 1
 

unique() üye fonksiyonun sahipliğin yalnızca bir shared_ptr tarafından tutulup tutulmadığınızı kontrol eder. C++17’den sonra deprecate edilmiştir.

if(spB2.unique())
	cout << "1 == spB2.use_count()";

// Output:
// 1 == spB2.use_count(
 

get() fonksiyonun shared_ptr’nin tuttuğu raw pointer’ı döndürür.

Book* rpB = spB2.get();

shared_ptr, raw pointer’ın iki katı kadar hafızada yer kaplar.

cout << "sizeof(spB2) " << sizeof(spB2) << '\n'
     << "sizeof(rpB) " << sizeof(rpB) << '\n';
// Output:
// sizeof(spB2) 16
// sizeof(rpB) 8
İsim Sahiplik Kopyalanma Taşınma Paylaşım
unique_ptr Tek
shared_ptr Çoklu Referans
weak_ptr