头文件#include
智能指针 智能:无论如何,保证资源 一定会释放
内存:.data .heap
利用栈上的对象出作用域自动析构的特点,把
资源释放的代码,放在智能指针的析构函数里面
auto_ptr C++11之前 C++库里面有的
只有最后一个智能指针有效
scoped_ptr 把拷贝构造和operator=给delete掉了
#include
unique_ptr 把拷贝构造和operator=给delete掉了
#include
unique_ptr 把拷贝构造和operator=给delete掉了
带引用计数的智能指针(一个资源 =》 多个智能指针)
#include
shared_ptr 强(引起资源引用计数的改变)智能指针
weak_ptr 弱(不会引起资源引用计数的改变)智能指针
// ++ --操作 加锁的方式 CAS方式
是线程安全的智能指针
智能指针的删除器Deletor:自定义资源的释放方式 一元函数对象operator()
=======================================================
1> 带引用计数的智能指针的循环应用问题
2> 带引用计数的智能指针能不能解决多线程访问共享对象的线程安全问题
3> unique_ptr到底怎么回事
class B;
class A
{
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
weak_ptr _ptrb;
void testA() { cout << "A类中很强大的一个方法实现!" << endl; }
};
class B
{
public:
B() { cout << "B()" << endl; }
~B() { cout << "~B()" << endl; }
weak_ptr _ptra;
// operator* operator->
void func()
{
// promote 提升 弱 -》 强(引用计数 1)
// shared_ptr operator== != nullptr
shared_ptr sp = _ptra.lock();
if (sp != nullptr)
{
// 提升成功了(说明资源还在)
sp->testA();
}
else
{
// 提升失败了(说明资源已经不存在了)
}
}
};
int main()
{
// 用引用计数解决问题,有一个bug
shared_ptr pa(new A());
shared_ptr pb(new B());
pa->_ptrb = pb;
pb->_ptra = pa;
cout << pa.use_count() << endl;
cout << pb.use_count() << endl;
pb->func();
return 0;
}
#endif
#if 0
// 记录资源的引用计数类 C++STL库里面容器的增加,删除 不是线程安全
class RefCnt
{
public:
// 给资源添加引用计数
void add(void *ptr)
{
auto it = mrefCntMap.find(ptr);
if (it != mrefCntMap.end())
{
it->second++;
}
else
{
// make_pair(ptr,1);
mrefCntMap.insert({ ptr, 1 });
}
}
// 给资源减少引用计数
void del(void *ptr)
{
auto it = mrefCntMap.find(ptr);
if (it != mrefCntMap.end())
{
if (--(it->second) == 0)
{
//mrefCntMap.erase(it);
}
}
}
// 返回指定资源的引用计数
int get(void *ptr)
{
auto it = mrefCntMap.find(ptr);
if (it != mrefCntMap.end())
{
return it->second;
}
return 0;
}
private:
// 一个资源void* 《=》 计数器 int
unordered_map mrefCntMap;
};
// 提供一个默认的删除器,默认删除的是堆内存资源
template
class Deletor
{
public:
void operator()(T *ptr) // 一元函数对象
{
delete ptr; // 默认删除的是堆内存资源
}
};
// 自定义的智能指针 T资源的类型 D删除器的类型
template>
class CSmartPtr
{
public:
// 构造函数
CSmartPtr(T *ptr = nullptr, const D &d=D())
:mptr(ptr), mdeletor(d)
{
if (mptr != nullptr)
{
mrefCnt.add(mptr);
}
}
~CSmartPtr()
{
mrefCnt.del(mptr);
if (0 == mrefCnt.get(mptr))
{
cout << "释放默认的堆内存资源" << endl;
mdeletor(mptr); // 通过删除器来释放资源
}
//delete mptr;
}
CSmartPtr(const CSmartPtr &src)
:mptr(src.mptr)
{
if (mptr != nullptr)
{
mrefCnt.add(mptr);
}
}
CSmartPtr& operator=(const CSmartPtr &src)
{
if (this == &src)
return *this;
mrefCnt.del(mptr);
if (0 == mrefCnt.get(mptr))
delete mptr;
mptr = src.mptr;
if (mptr != nullptr)
{
mrefCnt.add(mptr);
}
return *this;
}
/* auto_ptr的实现方式
CSmartPtr(CSmartPtr &src)
{
mptr = src.release();
}
T* release()
{
T *ptmp = mptr;
mptr = nullptr;
return ptmp;
}*/
// 指针常用运算符重载函数
T& operator*() { return *mptr; }
const T& operator*()const { return *mptr; }
T* operator->() { return mptr; }
// scoped_ptr的实现方式
// CSmartPtr(const CSmartPtr&) = delete;
// CSmartPtr& operator=(const CSmartPtr&) = delete;
private:
T *mptr; // FILE *pf; delete pf; fclose(pf);
D mdeletor;
static RefCnt mrefCnt;
};
template
RefCnt CSmartPtr::mrefCnt;
int main()
{
// 智能指针 管理资源 =》 堆内存 文件
CSmartPtr ptr2(new int);
class FileDeletor
{
public:
void operator()(FILE *pf) const
{
cout << "释放文件资源" << endl;
fclose(pf);
}
};
CSmartPtr ptr(fopen("data.txt", "w+"));
// mdeletor(mptr);
// CSmartPtr ptr3(fopen("data1.txt", "w+"), [](FILE *pf)->void { cout << "xxx" << endl; });
// delete p;
unique_ptr ptr3(new int);
unique_ptr ptr4(fopen("d", "w+"));
unique_ptr ptr5(fopen("dd", "w+")});
return 0;
}
// 自定义的智能指针
template
class CSmartPtr
{
public:
// 构造函数
CSmartPtr(T *ptr = nullptr)
:mptr(ptr)
{
if (mptr != nullptr)
{
mrefCnt.add(mptr);
}
}
~CSmartPtr()
{
mrefCnt.del(mptr);
if(0 == mrefCnt.get(mptr))
delete mptr;
}
CSmartPtr(const CSmartPtr &src)
:mptr(src.mptr)
{
if (mptr != nullptr)
{
mrefCnt.add(mptr);
}
}
CSmartPtr& operator=(const CSmartPtr &src)
{
if (this == &src)
return *this;
mrefCnt.del(mptr);
if (0 == mrefCnt.get(mptr))
delete mptr;
mptr = src.mptr;
if (mptr != nullptr)
{
mrefCnt.add(mptr);
}
return *this;
}
/* auto_ptr的实现方式
CSmartPtr(CSmartPtr &src)
{
mptr = src.release();
}
T* release()
{
T *ptmp = mptr;
mptr = nullptr;
return ptmp;
}*/
// 指针常用运算符重载函数
T& operator*() { return *mptr; }
const T& operator*()const { return *mptr; }
T* operator->() { return mptr; }
// scoped_ptr的实现方式
// CSmartPtr(const CSmartPtr&) = delete;
// CSmartPtr& operator=(const CSmartPtr&) = delete;
private:
T *mptr;
static RefCnt mrefCnt;
};
template
RefCnt CSmartPtr::mrefCnt;
int main()
{
CSmartPtr ptr1(new int);
CSmartPtr ptr2 = ptr1;
*ptr2 = 20;
*ptr1 = 30;
CSmartPtr ptr3(new int);
ptr2 = ptr3;
auto_ptr p;
// auto_ptr能不能用在容器当中
/* vector> vec;
vec.push_back(auto_ptr(new int));
vector> vec1 = vec;
*/
return 0;
}
#if 0
int main()
{
CSmartPtr ptr1(new int);
*ptr1 = 20; // T operator*()
class Test
{
public:
void test() { cout << "call Test::test" << endl; }
};
CSmartPtr ptr2(new Test());
ptr2->test(); // (ptr2.operator->())->test();
(*ptr2).test();
// 能不能在堆上直接定义智能指针
//CSmartPtr *ptr2 = new CSmartPtr(new int);
//delete ptr2;
return 0;
}
class CMemLeakCheck
{
public:
~CMemLeakCheck()
{
}
private:
unordered_set
};
// 定义一个内存泄露检查的全局对象
CMemLeakCheck memleakCheck;
int main()
{
// C++11 右值引用 左值引用(叫得上名字,取得上地址)
int a = 10;
int &b = a;
const int &c = 20; // c = 30;
int &&d = 20;
d = 30;
return 0;
}
template
class CStack
{
public:
CStack(int size = 100000)
:mtop(0)
{
cout << "CStack()" << endl;
mpstack = new T[size];
}
~CStack()
{
cout << "~CStack()" << endl;
delete[]mpstack;
}
CStack(const CStack &src)
:mtop(src.mtop)
{
cout << "CStack(const CStack &src)" << endl;
mpstack = new T[100000];
for (int i = 0; i < mtop; ++i)
{
mpstack[i] = src.mpstack[i];
}
//mpstack = src.mpstack;
//src.mpstack = nullptr;
}
// 提供带右值引用参数的拷贝构造函数
CStack(CStack &&src)
:mtop(src.mtop)
{
cout << "CStack(CStack &&src)" << endl;
mpstack = src.mpstack;
src.mpstack = nullptr;
}
CStack& operator=(const CStack &src)
{
cout << "operator=" << endl;
if (this == &src)
return *this;
delete[]mpstack;
mtop = src.mtop;
mpstack = new T[100000];
for (int i = 0; i < mtop; ++i)
{
mpstack[i] = src.mpstack[i];
}
return *this;
}
CStack& operator=(CStack &&src)
{
cout << "operator=(&&)" << endl;
if (this == &src)
return *this;
delete[]mpstack;
mtop = src.mtop;
mpstack = src.mpstack;
src.mpstack = nullptr;
return *this;
}
void push(const T &val)
{
mpstack[mtop++] = val;
}
private:
T *mpstack;
int mtop;
};
CStack GetStackObject()
{
CStack s;
s.push(20);
s.push(30);
s.push(40);
return s;
}
int main()
{
CStack s1;
CStack s2(std::move(s1)); // std::move
s2 = GetStackObject();
return 0;
}
tring name; 种类名称
Action action;动作
Time time:时间
class Function
{
public:
// map>
list getAction(string name);
// map
new int(10)
new nothorw int(10);
new (addr) int(10);
const int * p = new const int(10);
函数对象
greater less greater_equal less_equal
// C++实现垃圾回收器 new Node delete (Node*)ptr;
// 对象池的初始个数
const int MEM_NODE_SIZE = 5;
template
class CLink
{
public:
CLink() { mphead = new Node(); }
~CLink();
void insertTail(const T &val);
void removeHead();
void show();
private:
struct Node
{
Node(T data = T()) :mdata(data), mpnext(nullptr) {}
/*
给Node类型提供new和delete运算符的重载,
自定义Node对象的内存管理方式,实现Node对象池功能
*/
void* operator new(size_t size)
{
if(mpObjectPool ==nullptr)
{
mpObjectPool =
(Node *)new char(MEM_NODE_SIZE *sizeof (Node ));
Node *pcur=mpObjectPool ;
for(;pcur mpnext =pcur+1;
}
pcur ->mpnext =nullptr;
}
Node *palloc=mpObjectPool ;
mpObjectPool =mpObjectPool ->mpnext;
return palloc ;
}
void operator delete(void *ptr)
{
Node *pfree=(Node *)ptr;
pfree ->mpnext =mpObjectPool ;
mpObjectPool=pfree ;
}
T mdata;
Node *mpnext;
// 添加一个指向对象池的起始地址的指针
static Node *mpObjectPool;
};
Node *mphead;
};
int main()
{
return 0;
}
class Test
{
public:
Test() :mptr(new int(0)) { cout << "Test()" << endl; }
~Test() { delete mptr; cout << "~Test()" << endl; }
// Test对象的内存开辟释放会调用到这里 默认都是static方法
void* operator new(size_t size) // 只负责内存开辟
{
void *p = nullptr;
p = malloc(size);
if (p == nullptr)
throw bad_alloc();
cout << "operator new addr: " << p << endl;
return p;
}
void operator delete(void *ptr) // 只负责释放内存
{
cout << "operator delete addr:" << ptr << endl;
free(ptr);
}
void* operator new[](size_t size) // 只负责内存开辟
{
void *p = nullptr;
p = malloc(size);
if (p == nullptr)
throw bad_alloc();
cout << "operator new[] addr:" << p << endl;
return p;
}
void operator delete[](void *ptr) // 只负责释放内存
{
cout << "operator delete[] addr:" << ptr << endl;
free(ptr);
}
private:
int *mptr;
};
1.malloc 库函数 new运算符
2.malloc new
3.malloc(void*) new int(10)
4.malloc new int20;
1.delete 析构 free
2.delete free
Test p = new Test;
3.delete (int)p;(敏感) free(ptr);
4.free(ptr) delete []ptr;
#if 0
class Test
{
public:
Test(const char *ptr) :mptr(new char[strlen(ptr) + 1])
{
cout << "Test()" << endl;
strcpy(mptr, ptr);
}
~Test()
{
cout << "~Test()" << endl;
delete[]mptr;
mptr = nullptr;
}
void show() { cout << mptr << endl; }
private:
char *mptr;
};
// 子线程 p
void thread_proc(weak_ptr wp, const char *threadname)
{
cout << threadname << endl;
// 睡眠2s
std::this_thread::sleep_for(std::chrono::seconds(2));
cout << "子线程2s睡眠已到!" << endl;
//p->show();
/*
这个线程在提升的过程中,刚好其它线程在释放
*/
shared_ptr sp = wp.lock(); // 2-1 = 1
if (sp != nullptr)
{
sp->show();
}
else
{
cout << "Test对象已经析构,不能继续访问!" << endl;
}
}
void func()
{
//Test *p = new Test("hello world");
shared_ptr p(new Test("hello world"));
// 创建线程对象,就自动开启线程了
/*
thread(xx, shared_ptr p)
*/
thread t1(thread_proc, weak_ptr(p), "child thread");
// pthread_create
t1.join();
//t1.detach(); // 设置子线程为分离线程
//delete p;
// t1.join pthread_join
// t1.detach pthread_detach 设置分离线程
cout << "main thread end!" << endl;
} //1 - 1 = 0
int main()
{
cout << "main thread begin!" << endl;
func();
// 主线程等待20秒,查看子线程的运行情况
std::this_thread::sleep_for(std::chrono::seconds(20));
return 0;
}