class HeapOnly
{
public:
void Destory()
{
delete this;//this指向的就是需要释放的资源
//this = nullptr;
//说明:this 指针是 T * const this 类型的 即this指针不可被修改!因此无法置空
}
private:
~HeapOnly()
{
//...
}
};
class HeapOnly
{
public:
//static 公有成员函数可以直接通过类访问限定符进行访问。
static HeapOnly* CreatHeapOnly()
{
return new HeapOnly;
}
//其实不加static也可以调用,想一下如何实现。
private:
//防止new出来的对象再进行拷贝构造局部对象
HeapOnly(const HeapOnly& v) = delete;
//赋值要不要封呢?可以封,不过没有必要,因为赋值是已存在的两个对象进行的赋值操作
//我们封的是对已存在的对象进行初始化的操作。
//防止生成局部对象
HeapOnly()
{
//...
}
};
class NoneHeap
{
public:
static NoneHeap CreatHeapObj()
{
NoneHeap st;
return st;//此处类外需要调用拷贝构造,因此无法对拷贝构造进行私有。
}
private:
//把构造私有化
NoneHeap()
{
//...
}
void* operator new(size_t);
//通过对new的理解——调用operator new + 构造函数。
//这里的拷贝构造是无法进行实现的屏蔽的,这里的拷贝构造创建对象需要使用.
//因此无法进行屏蔽,所以只能通过封闭new来封闭堆空间的开辟。
//那既然这样对构造函数的封闭就显得无关紧要了。
void operator delete(void*);
};
class NoneHeap
{
public:
//把构造私有化
NoneHeap()
{
//...
}
private:
void* operator new(size_t);
void operator delete(void*);
};
缺陷:无法禁用static对象和全局对象的创建。
class NoneCopy
{
public:
private:
NoneCopy(const NoneCopy& v);
};
class NoneCopy
{
public:
NoneCopy(const NoneCopy& v) = delete;
};
细节:这里的编译器不会再生成默认构造函数,因为写了拷贝构造(即使是声明也算写了)。
class NoneInherit final// 语法层面禁用
{
};
//class A : public NoneInherit
//{
//
//};
//写出来直接报错
class NoneInherit
{
private:
NoneInherit ()
{
//...
}
NoneInherit (const NoneInherit & n)
{
//...
}
};
//class A : public NoneInherit
//{
//
//};
//不会报错,只会在实例化的时候进行报错。
class Hungry
{
public:
static Hungry& GetInstance()
{
return _s;
}
//进行添加数据的操作
void AddInstance(string str)
{
_infor.push_back(str);
}
void Print()
{
for (auto& e : _infor)
{
cout << e << " ";
}
cout << endl;
}
private:
//1.将构造函数私有化
Hungry()
{}
//3.拷贝构造进行删除
Hungry(const Hungry& s) = delete;
//赋值为什么要删除?可以不用删除吗?
//Hungry& operator=(Hungry s) = delete;
vector<string> _infor;//方便测试
//2.定义一个static
static Hungry _s;//这里只是声明
//Hungry _s;从原理上看这里会陷入死循环。
};
Hungry Hungry::_s ;//这里是定义。
//细节:由于_s的作用域是类域不是全局域,因此可以调用私有的构造函数。
int main()
{
Hungry::GetInstance().AddInstance("hello");
Hungry::GetInstance().AddInstance("world");
Hungry::GetInstance().AddInstance("hello");
Hungry::GetInstance().Print();
return 0;
}
class Lazy
{
public:
static Lazy& GetInstance()
{
//判断一下对象是否为空指针
if (_lazy == nullptr)
_lazy = new Lazy;
return *_lazy;
}
//需要手动进行释放
static void DestroyInstance()
{
delete _lazy;//先调用析构函数对资源进行处理 再对空间进行释放。
_lazy = nullptr;
}
~Lazy()
{
//对资源进行处理——这里只是举个样例:将资源写到文件中。
FILE* fout = fopen("text1.txt", "a");
for (auto& e : _infor)
{
fputs(e.c_str(), fout);
fputs(" ", fout);
}
fclose(fout);
}
//进行添加数据的操作
void AddInstance(string str)
{
_infor.push_back(str);
}
void Print()
{
for (auto& e : _infor)
{
cout << e << " ";
}
cout << endl;
}
private:
//1.将构造函数私有化
Lazy()
{}
//3.拷贝构造进行删除
Lazy(const Lazy& s) = delete;
//赋值
Lazy operator = (const Lazy& v) = delete;
private:
vector<string> _infor;
//2.定义一个static
static Lazy* _lazy;//这里只是声明
};
//懒汉模式是由指针管,最后还需要进行手动释放,
//此时我们可以运用RAII思想进行自动释放。
class Gc
{
public:
~Gc()
{
Lazy::DestroyInstance();
}
};
Gc g;//全局对象在程序结束时自动调用析构函数进行清理资源。
//程序结束也应该调用析构函数,这里是手动释放,此时可使用RAII思想
int main()
{
Lazy::GetInstance().AddInstance("hello");
Lazy::GetInstance().AddInstance("world");
Lazy::GetInstance().AddInstance("xxxx");
Lazy::GetInstance().Print();
Lazy::DestroyInstance();
Lazy::GetInstance().AddInstance("dict");
Lazy::GetInstance().AddInstance("single");
Lazy::GetInstance().AddInstance("hungry");
Lazy::GetInstance().Print();
return 0;
}
细节:最后如果交给Gc可不用手动释放,否则还需要手动释放,其次这里的懒汉模式可以在中途对资源进行清理再进行使用(用的不多)。
今天的分享就到此结束了,有错误请及时纠正,我是舜华,期待与你的下一次相遇!