【牛客带你学编程C++方向】项目练习第3期(截止3.27)


C++项目练习:第3期
练习时间:3月13日-3月27日(2周)
活动规则:
  • 每一期一个项目,届时会开新帖发布
  • 学员直接将答案提交到该贴评论区即可
  • 两周后,公布导师参考答案
  • 导师评选出当期最佳代码(将设置为精彩回复

奖励:牛客大礼包一份(牛客定制水杯 牛客定制笔 牛客定制程序员徽章 滑稽抱枕)
参与方式:直接将你的代码回复到本帖评论区

----------------------------------------------------

本期题目:

实现C++的智能指针类,也就是自己实现一个和C++的shared_ptr同样功能的类。

参与方式:直接将你的代码回复到本帖评论区

全部评论
#include <iostream> using namespace std; template<class T> class SmartPtr { public:     SmartPtr(T *p){         try         {             use_count = new int(1);         }         catch (...)         {             delete ptr;             ptr = nullptr;             use_count = nullptr;             cout << "Allocate memory for use_count fails." << endl;             exit(1);         }         cout << "Constructor is called!" << endl;     }     ~SmartPtr(){         // 只在最后一个对象引用ptr时才释放内存         if (--(*use_count) == 0)         {             delete ptr;             delete use_count;             ptr = nullptr;             use_count = nullptr;             cout << "Destructor is called!" << endl;         }     }     SmartPtr(const SmartPtr<T> &orig){         // 浅拷贝         ptr = orig.ptr;         use_count = orig.use_count;         ++(*use_count);         cout << "Copy constructor is called!" << endl;     }     SmartPtr<T>& operator=(const SmartPtr<T> &rhs){         // 浅拷贝         ++(*rhs.use_count);         // 将左操作数对象的使用计数减1,若该对象的使用计数减至0,则删除该对象         if (--(*use_count) == 0)         {             delete ptr;             delete use_count;             cout << "Left side object is deleted!" << endl;         }         ptr = rhs.ptr;         use_count = rhs.use_count;         cout << "Assignment operator overloaded is called!" << endl;         return *this;     } private:     T *ptr;     // 将use_count声明成指针是为了方便对其的递增或递减操作     int *use_count; }; int main() {     // Test Constructor and Assignment Operator Overloaded     SmartPtr<int> p1(new int(0));     p1 = p1;     // Test Copy Constructor     SmartPtr<int> p2(p1);     // Test Assignment Operator Overloaded     SmartPtr<int> p3(new int(1));     p3 = p1;     cin.get();     return 0; }
点赞 回复 分享
发布于 2018-03-13 12:28
//前置声明 因为在使用sharedptr时可能会产生循环引用的缺陷,所以使用weakedptr进行辅助 template <class T> class WeakedPtr; template<class T> class MySharedPtr { public: //定义为友元类      friend class WeakedPtr<T>;      MySharedPtr(T* ptr =  NULL) :_ptr(ptr), _refCount(new int(1))      {}      ~MySharedPtr()      {           if (--(*_refCount) == 0)           {               delete _ptr;               delete _refCount;           }      }      //s1(s2)      MySharedPtr(const MySharedPtr<T>& sp) :_ptr(sp._ptr), _refCount(sp._refCount)      {           (*_refCount)++;      }      //sp1 = sp2      MySharedPtr<T>& operator=(MySharedPtr<T>& sp)      {               if (_ptr != sp._ptr)               {                    if (--(*_refCount) == 0)                    {                         delete _ptr;                         delete _refCount;                    }                    _ptr = sp._ptr;                    _refCount = sp._refCount;                    (*_refCount)++;               }           return *this;      }      //为了像指针一样才进行*\->的重载      //->的重载      T* operator->()      {           return _ptr;      }      //*的重载      T& operator*()      {           return *_ptr;      }      //查看引用计数的多少      int UseCount()      {           return *_refCount;      } private:      T* _ptr;      int* _refCount;//一块空间有一个指针 }; template <class T> class WeakedPtr { public:      WeakedPtr() :_ptr(NULL)      {}      WeakedPtr(const MySharedPtr<T>& sp)           :_ptr(sp._ptr)      {}      WeakedPtr<T>& operator=(const MySharedPtr<T>&sp)      {           _ptr = sp._ptr;           return *this;      }      T& operator* ()      {           return *_ptr;      }      T* operator->()      {           return _ptr;      } private:      T* _ptr; }; struct  ListNode {      int _data;      WeakedPtr<ListNode> _next;      WeakedPtr<ListNode> _prev;      ~ListNode()      {           cout << "~ListNode" << endl;      } }; void testMySharedPtr() {      //SharePtr<int> sp1(new int(1));      //SharePtr<int> sp2(sp1);      MySharedPtr<ListNode> cur(new ListNode);      MySharedPtr<ListNode> next(new ListNode);      cout << cur.UseCount() << endl;      cout << next.UseCount() << endl;      cur->_next = next;      next->_prev = cur;      cout << cur.UseCount() << endl;      cout << next.UseCount() << endl; }
点赞 回复 分享
发布于 2018-03-13 14:32
#include <iostream> using namespace std; template<typename T> class SharedPtr { public:     //禁止分配内存时抛出异常     explicit SharedPtr(T *p):ptr(p), use(new (nothrow) size_t(1))     {         //分配内存失败         if (use == nullptr)         {             delete ptr;             ptr = nullptr;             cout << "分配内存失败";             exit(-1);         }                 }     explicit SharedPtr(const SharedPtr &rhs) :ptr(rhs.ptr), use(rhs.use)     {         ++*use;     }     SharedPtr& operator=(const SharedPtr &rhs)     {         ++*rhs.use;         if (--*use == 0)         {             delete ptr;             ptr = nullptr;             delete use;             use = nullptr;         }         ptr = rhs.ptr;         use = rhs.use;         return *this;     }     T* get() const     {         return ptr;     }     size_t use_count() const     {         return *use;     }     bool unique() const     {         return use_count() == 1;     }     //交换两个指针的指向     void swap(SharedPtr &q)     {         SharedPtr temp(q);         q = *this;         *this = temp;     }     T& operator*() const     {         return *ptr;     }     T* operator->() const     {         return & operator*();     }     //虚析构函数     virtual ~SharedPtr()     {         if (--*use == 0)         {             delete ptr;             ptr = nullptr;             delete use;                         use = nullptr;                 }         } private:     T      *ptr;     size_t    *use; }; int main() {     //测试     SharedPtr<int> s1(new int(666));     {         SharedPtr<int> s2(s1);         SharedPtr<int> s3(s2);         cout << "*s1 = " << *s1 << endl;         cout << "s1 use_count " << s1.use_count() << endl;         cout << "s1 is unique? " << s1.unique() << endl;     }     SharedPtr<int> s4(new int(888));     SharedPtr<int> s5(s4);     cout << "Before swap:\n";     cout << "*s5 " << *s5 << endl;     cout << "*s1 " << *s1 << endl;     s5.swap(s1);     cout << "After swap:\n";     cout << "*s5 " << *s5 << endl;     cout << "*s1 " << *s1 << endl;     cout << *(s1.get()) << endl;     s1 = s4;     SharedPtr<double> pd1(new double(2.3333));     SharedPtr<double> pd2(new double(0.33333));     cout << "pd1 is unique? " << pd1.unique() << endl;     auto q = &pd1;     cout << "Before swap:\n";     cout << "*pd1 " << *pd1 << endl;     cout << "*pd2 " << *pd2 << endl;     q->swap(pd2);     cout << "After swap:\n";     cout << "*pd1 " << *pd1 << endl;     cout << "*pd2 " << *pd2 << endl;               cout << "test end!\n";     return 0; }
点赞 回复 分享
发布于 2018-03-19 22:01

相关推荐

10-14 14:12
已编辑
少儿频道 算法工程师
反向练手了属于是
牛客71321951号:秋招的每一步都在成为小丑王的路上狂奔
点赞 评论 收藏
分享
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务