1,你知道智能指針嗎?智能指針的原理。
2,常用的智能指針。
3,智能指針的實現。
1答案:智能指針是一個類,這個類的構造函數中傳入一個普通指針,析構函數中釋放傳入的指針。智能指針的類都是棧上的對象,所以當函數(或程序)結束時會自動被釋放,
2, 最常用的智能指針:
1)std::auto_ptr,有很多問題。 不支持複製(拷貝構造函數)和賦值(operator =),但複製或賦值的時候不會提示出錯。因爲不能被複制,所以不能被放入容器中。
2) C++11引入的unique_ptr, 也不支持複製和賦值,但比auto_ptr好,直接賦值會編譯出錯。實在想賦值的話,需要使用:std::move。
例如:
std::unique_ptr<int> p1(new int(5));
std::unique_ptr<int> p2 = p1; // 編譯會出錯
std::unique_ptr<int> p3 = std::move(p1); // 轉移所有權, 現在那塊內存歸p3所有, p1成爲無效的指針.
3) C++11或boost的shared_ptr,基於引用計數的智能指針。可隨意賦值,直到內存的引用計數爲0的時候這個內存會被釋放。
4)C++11或boost的weak_ptr,弱引用。 引用計數有一個問題就是互相引用形成環,這樣兩個指針指向的內存都無法釋放。需要手動打破循環引用或使用weak_ptr。顧名思義,weak_ptr是一個弱引用,只引用,不計數。如果一塊內存被shared_ptr和weak_ptr同時引用,當所有shared_ptr析構了之後,不管還有沒有weak_ptr引用該內存,內存也會被釋放。所以weak_ptr不保證它指向的內存一定是有效的,在使用之前需要檢查weak_ptr是否爲空指針。
3, 智能指針的實現
下面是一個基於引用計數的智能指針的實現,需要實現構造,析構,拷貝構造,=操作符重載,重載*-和>操作符。
- template <typename T>
- class SmartPointer {
- public:
- //構造函數
- SmartPointer(T* p=0): _ptr(p), _reference_count(new size_t){
- if(p)
- *_reference_count = 1;
- else
- *_reference_count = 0;
- }
- //拷貝構造函數
- SmartPointer(const SmartPointer& src) {
- if(this!=&src) {
- _ptr = src._ptr;
- _reference_count = src._reference_count;
- (*_reference_count)++;
- }
- }
- //重載賦值操作符
- SmartPointer& operator=(const SmartPointer& src) {
- if(_ptr==src._ptr) {
- return *this;
- }
- releaseCount();
- _ptr = src._ptr;
- _reference_count = src._reference_count;
- (*_reference_count)++;
- return *this;
- }
- //重載操作符
- T& operator*() {
- if(ptr) {
- return *_ptr;
- }
- //throw exception
- }
- //重載操作符
- T* operator->() {
- if(ptr) {
- return _ptr;
- }
- //throw exception
- }
- //析構函數
- ~SmartPointer() {
- if (--(*_reference_count) == 0) {
- delete _ptr;
- delete _reference_count;
- }
- }
- private:
- T *_ptr;
- size_t *_reference_count;
- void releaseCount() {
- if(_ptr) {
- (*_reference_count)--;
- if((*_reference_count)==0) {
- delete _ptr;
- delete _reference_count;
- }
- }
- }
- };
- int main()
- {
- SmartPointer<char> cp1(new char('a'));
- SmartPointer<char> cp2(cp1);
- SmartPointer<char> cp3;
- cp3 = cp2;
- cp3 = cp1;
- cp3 = cp3;
- SmartPointer<char> cp4(new char('b'));
- cp3 = cp4;
- }