简介
shared_ptr
代码
#include <iostream>
#include <memory>
using namespace std;
namespace smart_pointer
{
template <typename T>
struct defaultDeleter
{
void operator()(const T *ptr)
{
if (ptr)
{
delete ptr;
ptr = nullptr;
}
}
};
template <typename T, typename Deleter = defaultDeleter<T>>
class shared_ptr
{
public:
shared_ptr();
shared_ptr(T *ptr);
shared_ptr(const shared_ptr &sp); // 拷贝构造
shared_ptr(shared_ptr &&sp); // 移动构造
~shared_ptr();
T *operator->() const;
T &operator*() const;
operator bool() const;
shared_ptr &operator=(const shared_ptr &sp);
shared_ptr &operator=(shared_ptr &&sp);
T *get() const;
void reset(T *ptr);
void swap(shared_ptr &sp);
int count();
private:
atomic<int> *use_count;
T *ptr;
};
template <typename T, typename Deleter>
shared_ptr<T, Deleter>::shared_ptr()
{
}
template <typename T, typename Deleter>
shared_ptr<T, Deleter>::shared_ptr(T *_ptr)
: ptr(_ptr), use_count(new atomic<int>(1))
{
}
template <typename T, typename Deleter>
shared_ptr<T, Deleter>::shared_ptr(const shared_ptr &sp)
: ptr(sp.ptr), use_count(sp.use_count)
{
++*use_count;
}
template <typename T, typename Deleter>
shared_ptr<T, Deleter>::shared_ptr(shared_ptr &&sp)
{
std::swap(ptr, sp.ptr);
std::swap(use_count, sp.use_count);
}
template <typename T, typename Deleter>
shared_ptr<T, Deleter>::~shared_ptr()
{
if (ptr)
{
--*use_count;
if (*use_count <= 0)
{
Deleter()(ptr);
delete use_count;
cout << "shared_ptr dctor" << endl;
}
}
}
template <typename T, typename Deleter>
T *shared_ptr<T, Deleter>::operator->() const
{
return ptr;
}
template <typename T, typename Deleter>
T &shared_ptr<T, Deleter>::operator*() const
{
return *ptr;
}
template <typename T, typename Deleter>
shared_ptr<T, Deleter>::operator bool() const
{
return ptr != nullptr;
}
/* 异常安全赋值 */
template <typename T, typename Deleter>
shared_ptr<T, Deleter> &shared_ptr<T, Deleter>::operator=(const shared_ptr<T, Deleter> &sp)
{
#if 1
// copy and swap
shared_ptr<T, Deleter> tmp(sp);
swap(tmp);
return *this;
#else
// 自我赋值
if (sp.ptr == ptr)
return *this;
ptr = sp.ptr;
use_count = sp.use_count;
++*use_count;
return *this;
#endif
}
template <typename T, typename Deleter>
shared_ptr<T, Deleter> &shared_ptr<T, Deleter>::operator=(shared_ptr<T, Deleter> &&sp)
{
std::swap(ptr, sp.ptr);
std::swap(use_count, sp.use_count);
return *this;
}
template <typename T, typename Deleter>
T *shared_ptr<T, Deleter>::get() const
{
return ptr;
}
template <typename T, typename Deleter>
void shared_ptr<T, Deleter>::reset(T *_ptr)
{
shared_ptr<T, Deleter>().swap(*this);
ptr = _ptr;
use_count = new atomic<int>(1);
}
template <typename T, typename Deleter>
void shared_ptr<T, Deleter>::swap(shared_ptr<T, Deleter> &sp)
{
std::swap(ptr, sp.ptr);
std::swap(use_count, sp.use_count);
}
template <typename T, typename Deleter>
int shared_ptr<T, Deleter>::count()
{
return *use_count;
}
}; // namespace smart_pointer
int main(int argc, char *argv[])
{
{
smart_pointer::shared_ptr<int> p(new int(12));
smart_pointer::shared_ptr<int> p1(p);
*p1 = 2;
cout << *p << endl;
cout << p.count() << endl;
// 异常安全测试
p = p;
cout << *p << endl;
cout << p.count() << endl;
}
{
smart_pointer::shared_ptr<int> p(new int(12));
p.reset(new int(13));
cout << *p << endl;
// 右值赋值测试
p = smart_pointer::shared_ptr<int>(new int(14));
cout << *p << endl;
// 移动构造测试
smart_pointer::shared_ptr<int> p1(smart_pointer::shared_ptr<int>(new int(15)));
cout << *p1 << endl;
}
return 0;
}
实验结果
简化版
面试时上面代码很难在短时间内写完,可以参考下面的代码
#include <iostream>
#include <memory>
using namespace std;
namespace smart_pointer
{
template <typename T>
struct defaultDeleter
{
void operator()(const T *ptr)
{
if (ptr)
{
delete ptr;
ptr = nullptr;
}
}
};
template <typename T, typename Deleter = defaultDeleter<T>>
class shared_ptr
{
public:
shared_ptr();
shared_ptr(T *ptr);
shared_ptr(const shared_ptr &sp);
shared_ptr(shared_ptr &&sp);
~shared_ptr();
// T *operator->() const;
T &operator*() const;
int count();
// shared_ptr &operator=(const shared_ptr &sp);
// shared_ptr &operator=(shared_ptr &&sp);
private:
atomic<int> *use_count;
T *ptr;
};
template <typename T, typename Deleter>
shared_ptr<T, Deleter>::shared_ptr()
{
}
template <typename T, typename Deleter>
shared_ptr<T, Deleter>::shared_ptr(T *_ptr)
: ptr(_ptr), use_count(new atomic<int>(1))
{
}
template <typename T, typename Deleter>
shared_ptr<T, Deleter>::shared_ptr(const shared_ptr &sp)
: ptr(sp.ptr), use_count(sp.use_count)
{
++*use_count;
}
template <typename T, typename Deleter>
shared_ptr<T, Deleter>::shared_ptr(shared_ptr &&sp)
{
std::swap(ptr, sp.ptr);
std::swap(use_count, sp.use_count);
}
template <typename T, typename Deleter>
shared_ptr<T, Deleter>::~shared_ptr()
{
if (ptr)
{
--*use_count;
if (*use_count <= 0)
{
Deleter()(ptr);
delete use_count;
cout << "shared_ptr dctor" << endl;
}
}
}
template <typename T, typename Deleter>
T &shared_ptr<T, Deleter>::operator*() const
{
return *ptr;
}
template <typename T, typename Deleter>
int shared_ptr<T, Deleter>::count()
{
return *use_count;
}
};
int main()
{
smart_pointer::shared_ptr<int> p(new int(12));
smart_pointer::shared_ptr<int> p1(p);
*p = 33;
cout << *p << endl;
cout << p.count() << endl;
return 0;
}
面试实战
智能指针被问到多次,一般都是先简单按照自己的理解解释c++智能指针,然后有些面试官会要求自己手写一遍,如果可以仔细研究此代码,还是可以学到很多知识点的。
手写智能指针在今年的大厂面试中,自己也是遇到了多次,基本上有会要求手写一点,时间大概10分钟左右,所以平时在复习的时候,一定要十分熟练。开始的时候,自己以为看懂了就行了,结果在面试中高压环境下写代码的时候,会犯很多的错误,所以平时一定要自己多练习,规定时间内熟练的写出来。