1.当程序要求输入未知个数字符串时,应该
cin.getline();//输入一行字符串
RAII:对堆上空间进行自动化管理——利用对象自动析构的机制(Malloc-new)
(1)Auto_ptr
智能指针不能使用同一个裸指针( int* p = new int(10);
)赋值或者初始化多个Auto_ptr
不允许拷贝构造,不允许等号运算符重载,拷贝构造和等号运算符重载将源智能指针置空,p生成临时quto_ptr对象,使用临时对象拷贝构造a_p,析构使用临时对象,优化之后直接构造a_p
会因为析构多次所以会产生错误
void fun()
{
int* p = new int(10);
auto_ptr<int>a_p = p;//p生成临时auto_ptr对象,使用临时对象拷贝构造a_p,析构临时对象
//auto_ptr<int>a_p1(p);
cout << *p << endl;
cout << *a_p << endl;
}
mauto_ptr.h
#ifndef MAUTO_PTR_H
#define MAUTO_PTR_H
template<typename T>
class Mauto_ptr
{
public:
explicit Mauto_ptr(T* ptr = nullptr)//explicit防止隐式构造
:_ptr(ptr)
{}
Mauto_ptr(Mauto_ptr& src)
:_ptr(src.release())
{}
Mauto_ptr& operator=(Mauto_ptr& src)
{
_ptr = src.release();
}
~Mauto_ptr()//析构
{
delete _ptr;
}
T* release()
{
T* tmp = _ptr;
_ptr = NULL;
return tmp;
}
void reset()
{
delete _ptr;
_ptr = NULL;
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
private:
T* _ptr;
};
unique_ptr
unique_ptr不允许隐式构造,不允许使用同一个裸指针赋值或者初始化多个unique_ptr,不允许拷贝构造,不允许等号运算符重载
右值引用:用来引用即将死亡的对象——临时对象
munique_ptr.h
#ifndef MUNIQUE_PTR_H
#define MUNIQUE_PTR_H
template<typename T>
class Munique_ptr
{
public:
explicit Munique_ptr(T* ptr = nullptr)//explicit防止隐式构造
:_ptr(ptr)
{}
//Munique_ptr(Munique_ptr& src) = delete;//不允许拷贝构造
///Munique_ptr& operator=(Munique_ptr& src) = delete;
Munique_ptr(Munique_ptr&& src)
:_ptr(src.release())
{
}
Munique_ptr& operator=(Munique_ptr&& src)
{
_ptr = src.release();
}
~Munique_ptr()
{
delete _ptr;
}
T* release()
{
T* tmp = _ptr;
_ptr = NULL;
return tmp;
}
void reset()
{
delete _ptr;
_ptr = NULL;
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
operator bool()//没有返回值
{
return _ptr != NULL;
}
private:
T* _ptr;
};
#endif
shared_ptr
shared_ptr不允许使用隐式构造,不允许使用同一个裸指针赋值或者初始化多个shared_pt,允许等号运算符重载,允许拷贝构造,
mshared_ptr.h
#ifndef MSHARED_PTR_H
#define MSHARED_PTR_H
#include<map>
using namespace std;
template<typename T>
class Mshared_ptr
{
public:
explicit Mshared_ptr(T* ptr = nullptr)//explicit防止隐式构造
:_ptr(ptr)
{}
//Munique_ptr(Munique_ptr& src) = delete;
///Munique_ptr& operator=(Munique_ptr& src) = delete;
Mshared_ptr(Mshared_ptr& src)
{
/*
//判断插入是否成功
if (_count.insert(make_pair(_ptr, 2)).second == 0)
{
_count[_ptr]++;
}*/
_count.insert(make_pair(_ptr, 1));
_count[_ptr]++;
_ptr = src._ptr;
}
Mshared_ptr& operator=(Mshared_ptr&& src)
{
if (_ptr == src._ptr)
{
return *this;
}
if (unique())
{
_count.erase(_ptr);
delete _ptr;
}
else
{
_count[_ptr]--;
}
_ptr = src._ptr;
}
~Mshared_ptr()
{
if (unique())
{
_count.erase(_ptr);
delete _ptr;
}
else
{
_count[_ptr]--;
}
}
bool unique()
{
if (count.find(_ptr) == count.end() || count[_ptr] == 1)
{
return true;
}
return false;
}
T* release()
{
T* tmp = _ptr;
if (unique())
{
_count.erase(_ptr);
//delete _ptr;
}
else
{
_count[_ptr]--;
}
_ptr = NULL;
return tmp;
}
void reset()
{
if (unique())
{
_count.erase(_ptr);
delete _ptr;
}
else
{
_count[_ptr]--;
}
_ptr = NULL;
}
T& operator*()
{
return *_ptr;
}
T* operator->()
{
return _ptr;
}
operator bool()
{
return _ptr != NULL;
}
template<typename Ty>
friend class Mweak_ptr<Ty>
private:
static map<T*, int>* _count;
T* _ptr;
};
#endif
weak_ptr
weak_ptr弱智能指针,不能直接使用,如果要使用先要转化为强智能指针,弱智能指针不占用引用计数,只能由强智能指针构造弱智能指针。
Mwake_ptr.h
#ifndef MWEAK_PTR_H
#define MWEAK_PTR_H
#include"mshared_ptr.h"
template<typename T>
class Mweak_ptr
{
public:
Mweak_ptr(Mshared_ptr& s_ptr)
{
_s_ptr = s_ptr.get();
Mshared_ptr<T>::_count.insert(make_pair(_ptr, 1));
}
Mshared_ptr<T> lock()
{
if (Mshared_ptr<T>::_count.find(_s_ptr) != Mshared_ptr<T>::_count.end())
{
return Mshared_ptr<T>(_s_ptr);
}
return Mshared_ptr<T>();
}
private:
T* _s_ptr;
};
#endif
main.cpp
#include<iostream>
#include<map>
#include<memory>//智能指针
#include"mshared_ptr.h"
using namespace std;
template<typename T>
map<T*, int>* Mshared_ptr<T>::_count = new map<T*, int>();
/*
RAII 堆上空间进行自动化管理---利用对象自动析构的机制
malloc new
auto_ptr 废弃了
不能使用同一个裸指针赋值/初始化多个auto_ptr
拷贝构造和等号运算符 将源智能指针置空
不允许隐式构造
c++ 11
unique_ptr
不能使用同一个裸指针赋值/初始化多个unique_ptr
不允许隐式构造
不允许拷贝构造,不允许等号运算符重载
shared_ptr ------- 强智能指针
不允许隐式构造
不能使用同一个裸指针赋值/初始化多个shared_ptr
允许拷贝构造,允许等号运算符重载
weak_ptr ---- 弱智能指针
不占用引用计数
不能直接使用
如果要用需要先转为强智能指针
*/
unique_ptr<int> fun(unique_ptr<int>& ptr)
{
cout << *ptr << endl;
int* p = new int(9);
return unique_ptr<int>(p);
}
class B;
class A
{
public:
A()
{
cout << "A()" << endl;
}
~A()
{
cout << "~A()" << endl;
}
weak_ptr<B> _ptr_b;
};
class B
{
public:
B()
{
cout << "B()" << endl;
}
~B()
{
cout << "~B()" << endl;
}
weak_ptr<A> _ptr_a;
};
void fun()
{
shared_ptr<A> a_p(new A());
shared_ptr<B> b_p(new B());
shared_ptr<int> p(new int(10));
weak_ptr<int> w_p(p);
//w_p = p;
cout << *p << endl;
cout << *(w_p.lock()) << endl;
shared_ptr<int> tmp = w_p.lock();
a_p->_ptr_b = b_p;
b_p->_ptr_a = a_p;
/*
int * p = new int(11);
shared_ptr<int> s_p(p);
shared_ptr<int> s_p1(s_p);
//s_p = s_p1;
cout << s_p.use_count() << endl;
cout << *p << endl;
cout << *s_p << endl;
cout << *s_p1 << endl;
s_p.unique();
*/
#if 0
int* p = new int(10);
unique_ptr<int> u_p(p);
//unique_ptr<int> u_p1(p);
//u_p1 = u_p;
//cout << *p << endl;
//cout << *u_p << endl;
//u_p.get();
//u_p.release();
//u_p.reset();
//u_p.swap();
unique_ptr<int> u_p2(fun(u_p));
u_p2 = fun(u_p);
cout << *u_p2 << endl;
//if(u_p2)
//右值引用用来引用即将死亡的对象----临时对象
const int& a = 10;
int&& b = 10;
const int c = 10;
const int& d = c;
//int &&e = c;
#endif
#if 0
//int * p = new int(10);
auto_ptr<int> a_p(new int(10));
/*
p生成临时auto_ptr对象 ------- 隐式构造
使用临时对象拷贝构造a_p
析构临时对象
------优化 直接构造a_p
*/
//auto_ptr<int> a_p1(p);
auto_ptr<int> a_p2 = a_p;
a_p = a_p2;
a_p.release();//返回当前指向的地址,并将当前智能指针置空
a_p.reset();//将当前智能指针指向的内存的释放,指针置空
a_p.get();//获取智能指针内部指针
//cout << *a_p << endl;
#endif
}
int main()
{
fun();
system("pause");
return 0;
}