智能指针的使用

share_ptr

#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include <mutex>

struct Base {
	Base() {
		std::cout << "Base::Base()" << std::endl;
	}
	//note: non-virtual destruct is OK here
	~Base() {
		std::cout << "Base::~Base()\n";
	}
};

struct Derive : public Base {
	Derive() {
		std::cout << "Derive::Derive()" << std::endl;
	}
	~Derive() {
		std::cout << "Derive::~Derive()" << std::endl;
	}
};

void thr(std::shared_ptr<Base> p) {
	std::this_thread::sleep_for(std::chrono::seconds(1));
	std::shared_ptr<Base> lp = p; // thread-safe .
	// even though the shared use_count is incremented
	{
		static std::mutex io_mutex;
		std::lock_guard<std::mutex> lk(io_mutex);
		std::cout << "local pointer in a thread:  " << '\n' << "  lp.get()  "
			<< lp.get() << "   , lp.use_count() =   " << lp.use_count() << '\n';
	}
}

int main() {
	std::shared_ptr<Base> p = std::make_shared<Derive>();
	std::cout << "create a shared derive(as a pointer to base) \n" <<
		"p.get() =" << p.get() << ", p.use_count() =" << p.use_count() << '\n';
	std::thread t1(thr, p), t2(thr, p), t3(thr, p);
	p.reset(); //release ownership from main
	std::cout << "shared ownership between 3 threads and released\n"
		<< "ownership from main:\n" << "p.get() =" << p.get() << ", p.use_count()="
		<< p.use_count() << "\n";
	t1.join();
	t2.join();
	t3.join();
}

 

 

unique_ptr

#include <iostream>
#include <memory>
#include <vector>
#include <cstdio>
#include <fstream>
#include <cassert>
#include <functional>

struct B {
	virtual void bar() {
		std::cout << "B::bar \n";
	}
	virtual ~B() = default;
};

struct D : public B {
	D() {
		std::cout << "D::D\n";
	}
	~D() {
		std::cout << "D::~D\n";
	}
	void bar() override{
		std::cout << "D::bar\n";
	}
};

std::unique_ptr<D> pass_through(std::unique_ptr<D> p) {
	p->bar();
	return p;
}

void close_file(std::FILE *fp) {
	std::fclose(fp);
}

int main() {
	std::cout << "unique ownership semantics demo\n";
	{
		auto p = std::make_unique<D>(); //p is a unique_ptr that owns a D
		auto q = pass_through(std::move(p)); 
		assert(!p); // now p owns nothing and hold a null pointer
		q->bar(); //q owns D object
	} //~D called here

	std::cout << "runtime polymorphism demo \n";
	{
		std::unique_ptr<B> p = std::make_unique<D>(); //p is a unique_ptr that owns D object as a pointer to the base
		p->bar(); //virtual dispatch

		std::vector<std::unique_ptr<B>> v;
		v.push_back(std::make_unique<D>());
		v.push_back(std::move(p));
		v.emplace_back(new D);

		for (auto& p : v) {
			p->bar();
		}
	}  //~D calls three times

	std::cout << "custom deleter demo\n";
	std::ofstream("demo.txt") << 'x'; //prepare
	{
		std::unique_ptr<std::FILE, decltype(&close_file)> fp(std::fopen("demo.txt", "r"), &close_file);
		if (fp)  //fopen could have failed; in which cause fp holds a null pointer
			std::cout << (char)std::fgetc(fp.get()) << '\n';
	} //fclose() called here, but only if FILE* is not a null pointer

	std::cout << "Custom lambda-expression deleter demo\n";
	{
		std::unique_ptr<D, std::function<void(D*)>> p(new D, [](D* ptr) {
			std::cout << "destorying from a custom deleter...\n";
			delete ptr;
		});  // p owns D
		p->bar();
	} //  the lambda above is called and D is destoryed

	std::cout << "Array form unique_ptr demo\n";
	{
		std::unique_ptr<D[]> p{ new D[3] };
	}  //calls ~D three times 
}

 weak_ptr

#include <iostream>
#include <memory>

std::weak_ptr<int> gw;

void observe() {
	std::cout << "use_count == " << gw.use_count() << ": ";
	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 main() {
	{
		auto sp = std::make_shared<int>(42);
		gw = sp;
		observe();
	}
	observe();
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值