想让默认成员函数不实现功能可以通过以下两个方式:
1.只声明不实现(还会调用,只是没得内容可以执行)
2.在函数尾部添加 = delete 声明(直接向编译器表明没有这个函数了,不会调用)
具体用哪一种是具体情况具体分析,有时候是两个哪一种都行,有时候只能用其中一个。
一、只能在堆上创建
class Creat_heap_only
{
public:
static Creat_heap_only* Create()
{
return new Creat_heap_only;
}
private:
Creat_heap_only()
{}
Creat_heap_only(const Creat_heap_only& copy)
{}
const Creat_heap_only& operator=(Creat_heap_only& copy)
{}
};
构造函数拷贝构造函数得删除,以防有人在栈上创建,在栈上只能调用Create_heao_only* p = Create_heao_only::Create();创建新的对象。同时得自己delete p 或者整一个垃圾回收系统,这个系统在懒汉模式会提到。
二、只能在栈上创建
class Creat_stack_only
{
public:
Creat_stack_only()
{//...
}
void* operator new(size_t n) = delete;
void operator delete(void* del) = delete;
};
堆区对象创建和删除都是通过new和delete实现的,因此只需要重载operator函数,只声明不实现即可。
三、创建不能拷贝的对象
class cant_copy
{
//只声明不实现
cant_copy(const cant_copy& copy);
cant_copy& operator=(const cant_copy& copy);
};
对象拷贝是通过系统调用拷贝构造与赋值运算符重载实现的,因此只需要把这两个函数禁掉,只声明不实现即可。
四、设计一个无法被继承的类
class cant_inherit final
{
//....
};
c++11 开始支持final关键字,表明一个类是最终类,无法被继承
五、设计一个类,从始至终只能创建一个对象(单例模式)
饿汉就是饿了就得吃,所以事先得做好饭;懒汉就是拖延,需要了再去完成,不事先准备。
5.1 饿汉模式
饿汉模式指的是 这个对象被实际使用之前就得被创建好。就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象。
所谓成也萧何败也萧何,事先创建好唯一对象即是缺点,也是优点。
优点:事先创建好唯一对象,后续只管用,不管其他。代码简单。
缺点:其一,因为先创建好对象,所以启动慢,再万一要是你一直不用,资源也被白白浪费。其二,当多个唯一对象的类创建存在先后关系时,饿汉模式无法适配,原因在于程序启动就创建唯一对象,编译器只管创建对象,可不会管你创建对象时其他组件是否准备齐全。
class single_hungry
{
private:
single_hungry(){}
single_hungry(const single_hungry& copy) = delete;
single_hungry& operator=(const single_hungry& copy) = delete;
static single_hungry obj;
public:
static single_hungry* access()
{
return &obj;
}
};
single_hungry single_hungry::obj;
//使用
int main()
{
single_hungry*use = single_hungry::access();
return 0;
}
5.2 懒汉模式
懒汉模式就是:第一次使用实例对象时,创建对象。
优点:进程启动无负载。多个单例实例启动顺序自由控 制。
缺点:代码相对复杂
class single_lazy
{
public:
static single_lazy* access()
{
if (obj == nullptr)
{
obj = new single_lazy;
}
return obj;
}
private:
single_lazy() {};
single_lazy(const single_lazy& copy) = delete;
single_lazy& operator=(const single_lazy& copy) = delete;
static single_lazy* obj;
};
single_lazy* single_lazy::obj = nullptr;
int main()
{
single_lazy* use = single_lazy::access();
delete use;
return 0;
}
饿汉模式是直接创建了一个对象,而懒汉模式是创建了一个指针。懒汉模式第一次使用,即第一次调用access函数时,给这个指针分配空间(new)。因为懒汉模式是在堆区分配的空间,因此需要手动释放,而饿汉创建的对象是在静态区,因此随着程序结束,会自动释放。所以说,懒汉模式得自己释放空间,这就很麻烦,万一有的人忘了,这不就极易造成内存泄漏。那有没有一种办法,让程序自动帮我们释放?
很简单,创建一个与懒汉单例对象(堆区)同样生命周期的实例对象-回收对象(静态区),当程序结束生命周期结束时,回收对象析构函数设定成delete 懒汉单例对象指针即可。
class single_lazy
{
public:
static single_lazy* access()
{
if (obj == nullptr)
{
obj = new single_lazy;
}
return obj;
}
private:
single_lazy() {};
single_lazy(const single_lazy& copy) = delete;
single_lazy& operator=(const single_lazy& copy) = delete;
static single_lazy* obj;
struct recycle
{
~recycle()
{
delete obj;
}
};
static recycle rec;
};
single_lazy* single_lazy::obj = nullptr;
single_lazy::recycle single_lazy::rec;//程序结束 调rec的析构函数,就把obj指针指向的内容释放了