boost::shared_ptr
имеет необычный конструктор
template<class Y> shared_ptr(shared_ptr<Y> const & r, T * p);
и я немного озадачен тем, для чего это было бы полезно. По сути, он разделяет владение с r
, но .get()
вернет p
. не r.get()
!
Это означает, что вы можете сделать что-то вроде этого:
int main() {
boost::shared_ptr<int> x(new int);
boost::shared_ptr<int> y(x, new int);
std::cout << x.get() << std::endl;
std::cout << y.get() << std::endl;
std::cout << x.use_count() << std::endl;
std::cout << y.use_count() << std::endl;
}
И вы получите это:
0x8c66008
0x8c66030
2
2
Обратите внимание, что указатели являются отдельными, но оба они утверждают, что имеют use_count
из 2 (поскольку они совместно владеют одним и тем же объектом).
Таким образом, int
, принадлежащий x
, будет существовать до тех пор, пока существует x
или y
. И если я правильно понимаю документы, второй int
никогда не будет уничтожен. Я подтвердил это с помощью следующей тестовой программы:
struct T {
T() { std::cout << "T()" << std::endl; }
~T() { std::cout << "~T()" << std::endl; }
};
int main() {
boost::shared_ptr<T> x(new T);
boost::shared_ptr<T> y(x, new T);
std::cout << x.get() << std::endl;
std::cout << y.get() << std::endl;
std::cout << x.use_count() << std::endl;
std::cout << y.use_count() << std::endl;
}
Это выводит (как и ожидалось):
T()
T()
0x96c2008
0x96c2030
2
2
~T()
Итак ... в чем польза этой необычной конструкции, которая разделяет владение одним указателем, но действует как другой указатель (которым он не владеет) при использовании.