#include <iostream>
#include <memory>
#include <algorithm>
#include <string>
#include <vector>
#include <memory>
///////////////////////////////////////////////////////
// reference: http://en.cppreference.com/w/cpp/memory/weak_ptr
std::weak_ptr<int> gw;
void f()
{
if (auto spt = gw.lock()) // Has to be copied into a shared_ptr before usage
{
std::cout << *spt << "\n";
}
else
{
std::cout << "gw is expired\n";
}
}
int main1()
{
{
auto sp = std::make_shared<int>(42);
gw = sp;
f();
}
f();
return 0;
}
/////////////////////////////////////////////////
// reference: http://stackoverflow.com/questions/12030650/when-is-stdweak-ptr-useful
int main3()
{
// OLD, problem with dangling pointer
// PROBLEM: ref will point to undefined data!
int *ptr = new int(10);
int *ref = ptr;
delete ptr;
// NEW
// SOLUTION: check expired() or lock() to determine if pointer is valid
// empty definition
std::shared_ptr<int> sptr;
// takes ownership of pointer
sptr.reset(new int);
*sptr = 10; std::cout << "use count test 1:" << sptr.use_count() << '\n';
// get pointer to data without taking ownership
std::weak_ptr<int> weak1 = sptr; std::cout << "use count test 2:" << sptr.use_count() << '\n';
// deletes managed object, acquires new pointer
std::shared_ptr<int> sptr_bck = sptr;
std::cout << "use count test 3:" << sptr.use_count() << '\n';
std::cout << "use count test 3.5:" << sptr_bck.use_count() << '\n';
//sptr.reset(new int); std::cout << "use count test 4:" << sptr.use_count() << '\n';
*sptr = 5;
// get pointer to new data without taking ownership
std::weak_ptr<int> weak2 = sptr;
std::weak_ptr<int> weak3 = weak2;
std::cout << "use count test 5:" << sptr.use_count() << '\n';
// weak1 is expired!
if (auto tmp = weak1.lock())
std::cout << *tmp << '\n';
else
std::cout << "weak1 is expired\n";
// weak2 points to new data (5)
if (auto tmp = weak2.lock())
std::cout << *tmp << '\n';
else
std::cout << "weak2 is expired\n";
return 0;
}
//////////////////////////////////////////////////////
// reference: https://msdn.microsoft.com/en-us/library/hh279672.aspx
class Controller
{
public:
int Num;
std::string Status;
std::vector<std::weak_ptr<Controller>> others;
explicit Controller(int i) : Num(i), Status("On")
{
std::cout << "Creating Controller" << Num << std::endl;
}
~Controller()
{
std::cout << "Destroying Controller" << Num << std::endl;
}
// Demonstrates how to test whether the pointed-to memory still exists or not.
void CheckStatuses() const
{
for_each(others.begin(), others.end(), [](std::weak_ptr<Controller> wp)
{
try
{
auto p = wp.lock();
std::cout << "Status of " << p->Num << " = " << p->Status << std::endl;
}
catch (std::bad_weak_ptr b)
{
std::cout << "Null object" << std::endl;
}
});
}
};
void RunTest()
{
std::vector<std::shared_ptr<Controller>> v;
v.push_back(std::shared_ptr<Controller>(new Controller(0)));
v.push_back(std::shared_ptr<Controller>(new Controller(1)));
v.push_back(std::shared_ptr<Controller>(new Controller(2)));
v.push_back(std::shared_ptr<Controller>(new Controller(3)));
v.push_back(std::shared_ptr<Controller>(new Controller(4)));
// Each controller depends on all others not being deleted.
// Give each controller a pointer to all the others.
for (int i = 0; i < v.size(); ++i)
{
for_each(v.begin(), v.end(), [v, i](std::shared_ptr<Controller> p)
{
if (p->Num != i)
{
v[i]->others.push_back(std::weak_ptr<Controller>(p));
std::cout << "push_back to v[" << i << "]: " << p->Num << std::endl;
}
});
}
for_each(v.begin(), v.end(), [](std::shared_ptr<Controller> &p)
{
std::cout << "use_count = " << p.use_count() << std::endl;
p->CheckStatuses();
});
}
int main4()
{
RunTest();
std::cout << "Press any key" << std::endl;
char ch;
std::cin.getline(&ch, 1);
return 0;
}
////////////////////////////////////////////////
// reference: https://oopscenities.net/2014/08/03/c-smart-pointers-part-5-weak_ptr/
struct Child;
struct Parent
{
std::shared_ptr<Child> child;
~Parent() { std::cout << "Bye Parent" << std::endl; }
void hi() const { std::cout << "Hello" << std::endl; }
};
struct Child
{
//std::weak_ptr<Parent> parent;
std::shared_ptr<Parent> parent; // memory leak
~Child() { std::cout << "Bye Child" << std::endl; }
};
int main6()
{
auto parent = std::make_shared<Parent>();
auto child = std::make_shared<Child>();
parent->child = child;
child->parent = parent;
//child->parent.lock()->hi();
child->parent->hi();
return 0;
}
/////////////////////////////////////////////////////
// reference: http://thispointer.com/shared_ptr-binary-trees-and-the-problem-of-cyclic-references/
class Node
{
int value;
public:
std::shared_ptr<Node> leftPtr;
std::shared_ptr<Node> rightPtr;
// Just Changed the shared_ptr to weak_ptr
std::weak_ptr<Node> parentPtr;
Node(int val) : value(val)
{
std::cout << "Contructor" << std::endl;
}
~Node()
{
std::cout << "Destructor" << std::endl;
}
};
int main()
{
std::shared_ptr<Node> ptr = std::make_shared<Node>(4);
ptr->leftPtr = std::make_shared<Node>(2);
ptr->leftPtr->parentPtr = ptr;
ptr->rightPtr = std::make_shared<Node>(5);
ptr->rightPtr->parentPtr = ptr;
std::cout << "ptr reference count = " << ptr.use_count() << std::endl;
std::cout << "ptr->leftPtr reference count = " << ptr->leftPtr.use_count() << std::endl;
std::cout << "ptr->rightPtr reference count = " << ptr->rightPtr.use_count() << std::endl;
std::cout << "ptr->rightPtr->parentPtr reference count = " << ptr->rightPtr->parentPtr.lock().use_count() << std::endl;
std::cout << "ptr->leftPtr->parentPtr reference count = " << ptr->leftPtr->parentPtr.lock().use_count() << std::endl;
return 0;
}
备份地址: 【weak_ptr使用的几个实例】