天天看點

C++中shared_ptr與unique_ptr簡單使用一,shared_ptr二,unique_ptr

為了免除new與delete帶來的各種煩惱,C++11引入了更加好用更加健壯的智能指針供我們使用。

一,shared_ptr

為T類型的變量定義std::shared_ptr<T>共享指針

shared_ptr内部維護了資源引用數量的計數器。當不再有shared_ptr指向資源時,資源将自動被析構。預設調用delete函數。

使用資源時直接對共享指針 * 運算符解引用即可。

#include<cstdio>
#include<memory>

int main()
{
	std::shared_ptr<int> sp(new int(10));
	std::shared_ptr<int> sp2 = sp;
	printf("Shared_ptr=%p, Count=%d\n", sp.get(), sp.use_count());
	printf("Shared_ptr=%p, Count=%d\n", sp2.get(), sp2.use_count());
	sp.reset(); //sp取消引用
	printf("Shared_ptr=%p, Count=%d\n", sp2.get(), sp2.use_count());
	getchar();
	return 0;
}
           

運作結果:

Shared_ptr=00BA7AD8, Count=2

Shared_ptr=00BA7AD8, Count=2

Shared_ptr=00BA7AD8, Count=1

二,unique_ptr

unique_ptr實作的是以前auto_ptr類似的功能。

與shared_ptr可以使用多個指針引用資源不同的是,unique_ptr意味着資源最多隻能由一個指針進行引用。用另外一個unique_ptr指針取代先前的指針時,先前的指針将被強制修改為nullptr,對該指針解引用将導緻程式異常。

這時必須注意unique_ptr的指派隻能接受右值引用,否則編譯報錯。可以使用std::move()将左值轉換為右值引用。

可以使用調用delete的預設std::unique_ptr<T>構造,也可以使用std::unique_ptr<T, class Delete>調用自己的釋放資源的函數。

示例程式使用了後者,實作檔案在各種不同情況下都能夠正确關閉,避免了多次或者忘記了調用fclose()。

#include<cstdio>
#include<fstream>
#include<memory>

void close_file(std::FILE *fp) {
	std::fclose(fp);
	printf("File closed.\n");
}

int main()
{
	//std::auto_ptr<int> ap(new int(11));
	//printf("Auto_ptr=%X\n", ap);
	//std::auto_ptr<int> nap=ap;
	//printf("Old_Auto_ptr=%X\n", ap); //指向的内容被搶奪了
	
	std::ofstream("test.txt") << "!";

	{
		std::unique_ptr<FILE, decltype(&close_file)> fp(std::fopen("test.txt", "r"), &close_file);
		auto fp2 = std::move(fp);
		//auto fp3 = fp; unique_ptr指派運算符支援右值引用,不能使用左值
		printf("Old_one=%p, New_one=%p\n", fp.get(), fp2.get());
		if (fp2) {
			printf("Get '%c'.\n", fgetc(fp2.get()));
		}
	}
	getchar();
	return 0;
}
           

運作結果:

Old_one=00000000, New_one=00BE78A8

Get '!'.

File closed.

可以看到,在退出了fp的作用域之後,檔案被自動關閉了。

本來打算寫auto_ptr和shared_ptr相關的,結果到cppReference上一看,auto_ptr已經被廢棄使用了,C++17中甚至取消了對它的支援。不過C++給我的感覺是越來越臃腫,泛型比不過專業的面向對象語言,開源庫也不如其他語言豐富。雖然仍然最喜歡使用C++寫東西,但是以後C++還能維持它所處的地位嗎?