目录
1. 设计一个不能被拷贝的类
2. 设计一个只能在堆上创建的类
3. 设计一个只能在栈上创建的类
4. 设计一个不能被继承的类
5. 单例模式(设计一个类只创建一个对象)
1. 设计一个不能被拷贝的类
拷贝只会出现在拷贝构造函数和赋值重载函数里面; 想要防止拷贝就要从这两个函数入手.
有c++98和c++11两种处理方法:
c++98直接将这两个函数变成私有成员(外部无法使用)的并且只声明不定义(防止内部拷贝);
c++11是不是有个关键字delete.
class NonCopy
{
private:
NonCopy(const NonCopy&){}
NonCopy& operator=(const NonCopy&) {} = delete;
};
2. 设计一个只能在堆上创建的类
想一下如何在堆上创建对象,:
(1) new或者static静态类型, 其实只要静态成员函数即可;
(2) 然后还要防止在栈上创建对象, 那么就要将拷贝构造函数和赋值重载函数都私有化, 并且只声明不定义.
class HeapOnly
{
public:
static HeapOnly* creatobject()
{
return new HeapOnly;
}
private:
HeapOnly(){}
HeapOnly(const HeapOnly&) = delete;
};
int main()
{
//HeapOnly p;
HeapOnly::creatobject();
return 0;
}
3. 设计一个只能在栈上创建的类
和上面更好相反, 需要把new和delete(这里不是c++11里的delete, 是销毁空间的)禁止掉, 以及私有化;
class StackOnly
{
public:
static StackOnly creatobject()
{
return StackOnly();
}
void* operator new(size_t size) = delete;
void operator delete(void * p) = delete;
private:
StackOnly()
:_a(0)
{}
int _a;
};
4.设计一个不能被继承的类
c++98是直接将构造函数私有化, 子类就调不到基类的构造函数, 无法继承;
c++11是使用final关键字直接无法继承;
class NonInhert
{
public:
static NonInhert CreatNonInhert()
{
return NonInhert();
}
private:
NonInhert()
{}
};
class NonInhert final
{
...
}
5. 单例模式
啥是单例模式: 类中只能创建一个对象, 保证类中只有一个实例对象, 并提供一个访问它的全局访问点,该实例被所有程序模块共享.
有两种模式:饿汉模式和懒汉模式;
饿汉模式: 在使用之前就创建好;
懒汉模式; "现吃现做",
5.1饿汉模式
class Lazy
{
public:
static Lazy* GetInstance()
{
return &_inst;
}
void Add(const string& key, const string& value)
{
_dict[key] = value;
}
void print()
{
for (auto& kv : _dict)
{
cout << kv.first << kv.second << endl;
}
cout << endl;
}
private:
Lazy(){}
Lazy(const Lazy& aa) = delete;
Lazy& operator=(const Lazy& aa) = delete;
map<string, string> _dict;
int _n = 0;
static Lazy _inst;
};
Lazy Lazy::_inst;
int main()
{
//Lazy aa1;
Lazy::GetInstance()->Add("sort", "排序");
Lazy::GetInstance()->Add("left", "左边");
Lazy::GetInstance()->Add("right", "右边");
Lazy::GetInstance()->print();
/*Lazy copy(*Lazy::GetInstance());
copy.print();
//无法拷贝
Lazy::GetInstance()->Add("left", "剩余");
copy.print();
Lazy::GetInstance()->print();*/
//无法赋值
//*Lazy::GetInstance() = *Lazy::GetInstance();
return 0;
}
5.2 懒汉模式
class Singleton
{
public:
static Singleton* GetInstance()
{
if (_inst == nullptr)
{
_inst = new Singleton;
}
return _inst;
}
void Add(const string& key, const string& value)
{
_dict[key] = value;
}
static void DelInstance()
{
if (_inst)
{
delete _inst;
_inst = nullptr;
}
}
void print()
{
for (auto& kv : _dict)
{
cout << kv.first << ":" << kv.second << endl;
}
cout << endl;
}
private:
//将构造函数和析构函数都私有化
Singleton(){}
~Singleton()
{
cout << "数据写入文件" << endl;
}
//拷贝构造和赋值重载都禁掉,不允许其他类实例出对象
Singleton(const Singleton& aa) = delete;
Singleton& operator=(const Singleton& aa) = delete;
map<string, string> _dict;
int _n = 0;
class gc
{
public:
~gc()
{
DelInstance();
}
};
static Singleton* _inst;
static Singleton _Singleton;
};
Singleton* Singleton::_inst = nullptr;
int main()
{
Singleton::GetInstance()->Add("sort", "排序");
Singleton::GetInstance()->Add("left", "左边");
Singleton::GetInstance()->Add("right", "右边");
Singleton::GetInstance()->print();
Singleton::GetInstance()->Add("right", "xxx");
Singleton::GetInstance()->print();
Singleton::DelInstance();
cout << "xxxxxxxxxxx" << endl;
return 0;
}
5.3饿汉模式和懒汉模式的优缺点
饿汉模式:
优点:实现简单; 缺点: 可能导致进程启动慢, 如果有多个单例那么实例的时候无法确定顺序;
懒汉模式:
优点: 第一次使用实例对象时,创建对象。进程启动无负载。多个单例实例启动顺序自由控制。缺点:实现复杂.