C++11 auto_ptr shared_ptr unique_ptr

/*************************************************************************
	> File Name: ptr.cpp
	> Author: yangjx
	> Mail: [email protected] 
	> Created Time: Sat 18 Feb 2017 09:01:25 AM CST
 ************************************************************************/

#include<iostream>
#include<cstring>
#include<string>
#include<memory>

using namespace std;

class Simple
{
	public:
		Simple(int p = 0)
		{
			number = p;
			std::cout << "Simple::" << number << std::endl;
		}

		~Simple()
		{
			std::cout << "~Simple::" << number << std::endl;
		}

		void PrintSomething()
		{
			std::cout << "PrintSomething:" << info_extend.c_str() << std::endl;
		}

		std::string info_extend;
		int number;
};

void TestAutoPtr()
{
	std::auto_ptr<Simple> my_memory(new Simple(1));
	if(my_memory.get())
	{
		my_memory->PrintSomething();

		my_memory.get()->info_extend = "Additon";
		my_memory->PrintSomething();

		(*my_memory).info_extend += "other";
		my_memory->PrintSomething();
	}
}
/*
 * 上述爲正常使用 std::auto_ptr 的代碼,一切似乎都良好,無論如何不用我們顯示使用該死的 delete 了。
 * */

void TestAutoPtr2()
{
	std::auto_ptr<Simple> my_memory(new Simple(1));
	if(my_memory.get())
	{
		std::auto_ptr<Simple> my_memory2;
		my_memory2 = my_memory;
		my_memory2->PrintSomething();
		my_memory->PrintSomething();
	}
}
/*
 * 最終如上代碼導致崩潰,如上代碼時絕對符合 C++ 編程思想的,居然崩潰了,跟進 std::auto_ptr 的源碼後,我們看到,罪魁禍首是“my_memory2 = my_memory”,這行代碼,my_memory2 完全奪取了 my_memory 的內存管理所有權,導致 my_memory 懸空,最後使用時導致崩潰。
 * 所以,使用 std::auto_ptr 時,絕對不能使用“operator=”操作符。作爲一個庫,不允許用戶使用,確沒有明確拒絕[1],多少會覺得有點出乎預料。
 * */

void TestAutoPtr3()
{
	std::auto_ptr<Simple> my_memory(new Simple(1));
	if(my_memory.get())
		my_memory.release();

}
/*
 * 執行結果爲:
 * Simple: 1
 * 看到什麼異常了嗎?我們創建出來的對象沒有被析構,沒有輸出“~Simple: 1”,導致內存泄露。當我們不想讓 my_memory 繼續生存下去,我們調用 release() 函數釋放內存,結果卻導致內存泄露(在內存受限系統中,如果my_memory佔用太多內存,我們會考慮在使用完成後,立刻歸還,而不是等到 my_memory 結束生命期後才歸還)。
 * */

void TestAutoPtr4()
{
	std::auto_ptr<Simple> my_memory(new Simple(1));
	if(my_memory.get())
	{
		Simple* temp_memory = my_memory.release();
		delete temp_memory;
	}

}
void TestAutoPtr5()
{
	std::auto_ptr<Simple> my_memory(new Simple(1));
	if(my_memory.get())
	{
		my_memory.reset();
	}

}
/*
 * 原來 std::auto_ptr 的 release() 函數只是讓出內存所有權,這顯然也不符合 C++ 編程思想。
 * 總結:std::auto_ptr 可用來管理單個對象的對內存,但是,請注意如下幾點:
 * (1)    儘量不要使用“operator=”。如果使用了,請不要再使用先前對象。
 * (2)    記住 release() 函數不會釋放對象,僅僅歸還所有權。
 * (3)    std::auto_ptr 最好不要當成參數傳遞(讀者可以自行寫代碼確定爲什麼不能)。
 * (4)    由於 std::auto_ptr 的“operator=”問題,有其管理的對象不能放入 std::vector 等容器中。
 * (5)    ……
 * 使用一個 std::auto_ptr 的限制還真多,還不能用來管理堆內存數組,這應該是你目前在想的事情吧,我也覺得限制挺多的,哪天一個不小心,就導致問題了。
 * 由於 std::auto_ptr 引發了諸多問題,一些設計並不是非常符合 C++ 編程思想,所以引發了下面 boost 的智能指針,boost 智能指針可以解決如上問題。
 * */

//////////////////////////////////////////////////////////////

void TestSharedPtr()
{
	std::shared_ptr<Simple> my_memory(new Simple(1));
	if(my_memory.get())
	{
		my_memory->PrintSomething();

		my_memory.get()->info_extend = "Additon";
		my_memory->PrintSomething();

		(*my_memory).info_extend += "other";
		my_memory->PrintSomething();
	}

}
/*
 * 引入計數器 可從源碼瞭解到
 * */

void TestSharedPtr2()
{
	std::shared_ptr<Simple> my_memory(new Simple(1));
	if(my_memory.get())
	{
		std::shared_ptr<Simple> my_memory2;
		my_memory2 = my_memory;
		my_memory2->PrintSomething();
		my_memory->PrintSomething();
		std::cout << "use_count--> " << my_memory.use_count() << std::endl;
	}
}

///////////////////////////////////////////////////

void TestUniquePtr()
{
	std::unique_ptr<Simple> my_memory(new Simple(1));
	if(my_memory.get())
	{
		my_memory->PrintSomething();

		my_memory.get()->info_extend = "Additon";
		my_memory->PrintSomething();

		(*my_memory).info_extend += "other";
		my_memory->PrintSomething();
	}

}

void TestUniquePtr2()
{
	std::unique_ptr<Simple> my_memory(new Simple(1));
	if(my_memory.get())
	{
		std::unique_ptr<Simple> my_memory2 = std::move(my_memory);
		my_memory2->PrintSomething();
		my_memory->PrintSomething();
	}
}
/*
 * 執行錯誤
 * Simple::1
 * PrintSomething:
 * Segmentation fault (core dumped)
 * 主要原因源指針轉移給目標指針
 * std::unique_ptr實現了獨享所有權的語義。一個非空的std::unique_ptr總是擁有它所指向的資源。轉移一個std::unique_ptr將會把所有權也從源指針轉移給目標指針(源指針被置空)。
 *
 * 在C++11環境下,auto_ptr被看做“遺留的”,他們有如下區別:
 * auto_ptr有拷貝語義,拷貝後源對象變得無效;unique_ptr則無拷貝語義,但提供了移動語義
 * auto_ptr不可作爲容器元素,unique_ptr可以作爲容器元素
 * auto_ptr不可指向動態數組(儘管不會報錯,但不會表現出正確行爲),unique_ptr可以指向動態數組
 *
 * */

int main()
{
	TestUniquePtr2();
	return 0;
}




轉自: http://blog.csdn.net/xiejingfa/article/details/50750037

             http://jingyan.baidu.com/article/9f7e7ec0b785ae6f281554f6.html     

             http://blog.csdn.net/xiamentingtao/article/details/55510975                /* 原理介紹*/

             http://blog.csdn.net/pi9nc/article/details/12227887             /*unique_ptr 詳細介紹*/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章