C++ 之 智能指针实现
2017-08-10 14:03
267 查看
面试的时候,被问到了智能指针,之前的确看过C++ primer,然而,都忘掉了。。
。。自己实现了一下share_ptr。。写完以后翻了翻书,才发现,和书上的并不差多少。。
智能指针类型: share_ptr, weak_ptr, unique_ptr
template <typename T> class smartPtr
{
public:
smartPtr() :ptr(new T(0)), ptrCount(new int(1)) // 任何构造方式都能调用*p,不会出错,如果初始化为nullptr,调用*p会出错
{
cout <<"empty smart pointer construct ing ~~" <<endl;
}
smartPtr(const T t) :ptr(new T(t)), ptrCount(new int(1))
{
cout<<"smart pointer construct ing ~~"<<endl;
}
smartPtr(smartPtr &rhs) : ptr(rhs.ptr), ptrCount(&(++(*rhs.ptrCount))) //拷贝构造
{
cout<<"smart pointer copy construct ing~~"<<endl;
}
T& operator*()
{
//cout << "operator * is called" << endl;
return *ptr;
}
T* operator->()
{
//cout << "operator -> is called" << endl;
return &(operator *()); // c++ primer 504p, 委托给解引用运算符
}
int getCount()
{
return *( ptrCount);
}
smartPtr& operator=(smartPtr &rhs) //赋值运算符
{
//cout << "operator = is called" << endl;
(*( ptrCount))--;
(*(rhs.ptrCount))++;
if ((*ptrCount) == 0)
{
delete ptr;
delete ptrCount;
ptr = nullptr;
ptrCount = nullptr;
}
ptr = rhs.ptr;
ptrCount = rhs.ptrCount;
return *this;
}
~smartPtr()
{
cout << "destructor is called, count is "<<*( ptrCount) << endl;
if (--*ptrCount == 0)
{
delete ptr;
ptr = nullptr;
}
}
private:
int *ptrCount;
T * ptr;
};
用到的知识点
1. 模板,模板可以扩大传入参数的类型范围 比如,基本类型,int, double, string..这些应该都没什么问题,其他更复杂的类类型,可能需要定义一下 << 运算符
2. 运算符重载,根据share_ptr的特性,要有一个计数器,这样就必须重载 = (赋值运算符)。还有 * (解引用) 和 -->(成员访问)。 计数器的其他实现方法,可以参考(http://blog.csdn.net/hackbuteer1/article/details/7561235)
3. 构造函数,拷贝构造函数
4. 计数器,用指针类型,方便共享
测试例子:
int main(int argc,char *argv[])
{
smartPtr<int> p(42);
smartPtr<int> q;
smartPtr<int> r(p); //copy initialize
cout << "p = " << *p << "; q = " << *q << endl;
cout << "p count " << p.getCount() << "; q count " << q.getCount() << endl;
q = p;
cout << "after q=p q is " << *q << endl;
cout << "p count " << p.getCount() << "; q count " << q.getCount() << endl;
}结果:
正常测试效果看起来还可以,不知道有没有和我一样暴力的程序员,会写:
smartPtr<int> p=*(new smartPtr<int>(40));
这样的代码。 由于在new里面调用了一次构造函数,使得count多出了1,而无法正确释放。( new运算符 1. 返回一片raw空间 2. 调用构造函数 3. 返回指针 )
运行效果,如下:
如果有解决这个问题的方法,还望不吝赐教~~
菜鸟一枚,如果有错误,请留下您的高见~~Thanks~~
。。自己实现了一下share_ptr。。写完以后翻了翻书,才发现,和书上的并不差多少。。
智能指针类型: share_ptr, weak_ptr, unique_ptr
template <typename T> class smartPtr
{
public:
smartPtr() :ptr(new T(0)), ptrCount(new int(1)) // 任何构造方式都能调用*p,不会出错,如果初始化为nullptr,调用*p会出错
{
cout <<"empty smart pointer construct ing ~~" <<endl;
}
smartPtr(const T t) :ptr(new T(t)), ptrCount(new int(1))
{
cout<<"smart pointer construct ing ~~"<<endl;
}
smartPtr(smartPtr &rhs) : ptr(rhs.ptr), ptrCount(&(++(*rhs.ptrCount))) //拷贝构造
{
cout<<"smart pointer copy construct ing~~"<<endl;
}
T& operator*()
{
//cout << "operator * is called" << endl;
return *ptr;
}
T* operator->()
{
//cout << "operator -> is called" << endl;
return &(operator *()); // c++ primer 504p, 委托给解引用运算符
}
int getCount()
{
return *( ptrCount);
}
smartPtr& operator=(smartPtr &rhs) //赋值运算符
{
//cout << "operator = is called" << endl;
(*( ptrCount))--;
(*(rhs.ptrCount))++;
if ((*ptrCount) == 0)
{
delete ptr;
delete ptrCount;
ptr = nullptr;
ptrCount = nullptr;
}
ptr = rhs.ptr;
ptrCount = rhs.ptrCount;
return *this;
}
~smartPtr()
{
cout << "destructor is called, count is "<<*( ptrCount) << endl;
if (--*ptrCount == 0)
{
delete ptr;
ptr = nullptr;
}
}
private:
int *ptrCount;
T * ptr;
};
用到的知识点
1. 模板,模板可以扩大传入参数的类型范围 比如,基本类型,int, double, string..这些应该都没什么问题,其他更复杂的类类型,可能需要定义一下 << 运算符
2. 运算符重载,根据share_ptr的特性,要有一个计数器,这样就必须重载 = (赋值运算符)。还有 * (解引用) 和 -->(成员访问)。 计数器的其他实现方法,可以参考(http://blog.csdn.net/hackbuteer1/article/details/7561235)
3. 构造函数,拷贝构造函数
4. 计数器,用指针类型,方便共享
测试例子:
int main(int argc,char *argv[])
{
smartPtr<int> p(42);
smartPtr<int> q;
smartPtr<int> r(p); //copy initialize
cout << "p = " << *p << "; q = " << *q << endl;
cout << "p count " << p.getCount() << "; q count " << q.getCount() << endl;
q = p;
cout << "after q=p q is " << *q << endl;
cout << "p count " << p.getCount() << "; q count " << q.getCount() << endl;
}结果:
正常测试效果看起来还可以,不知道有没有和我一样暴力的程序员,会写:
smartPtr<int> p=*(new smartPtr<int>(40));
这样的代码。 由于在new里面调用了一次构造函数,使得count多出了1,而无法正确释放。( new运算符 1. 返回一片raw空间 2. 调用构造函数 3. 返回指针 )
运行效果,如下:
如果有解决这个问题的方法,还望不吝赐教~~
菜鸟一枚,如果有错误,请留下您的高见~~Thanks~~
相关文章推荐
- 智能指针(模拟实现auto_ptr,shared_ptr,scooeptr 以及定制删除器c++ 实现)
- C++ 智能指针实现
- c++ 复制控制和智能指针实现
- 智能指针:->和*运算符重载 + 模板技术 实现智能指针(C++)
- C++实现智能指针(shared_ptr和unique_ptr)与删除器
- 两个栈实现队列+两个队列实现栈----C++
- 决策树生成c++实现(不含剪枝)
- Python与C++ 遍历文件夹下的所有图片实现代码
- 《Leetcode系列》C++实现:1-two sum
- C++贪心算法实现马踏棋盘问题
- C++实现委托机制(二)
- c++和java类的简单实现
- C++实现输入一组数删除两相邻为奇数的值
- [C/C++]函数参数的入栈顺序与可变参数的实现
- 简单数据结构之 vector 栈(C++ vector 实现)
- C++实现贪吃蛇类
- C++实现爬楼梯问题
- c++httpPost实现
- C++ 0x 使用可变参数模板类 实现 C# 的委托机制
- 栈的C++实现