目录
一.请设计一个类,不能被拷贝
二. 请设计一个类,只能在堆上创建对象
三. 请设计一个类,只能在栈上创建对象
四. 请设计一个类,不能被继承
五. 请设计一个类,只能创建一个对象(单例模式)
1.饿汉模式
2.懒汉模式
拷贝只会放生在两个场景中:拷贝构造函数以及赋值运算符重载,因此想要让一个类禁止拷贝,
只需让该类不能调用拷贝构造函数以及赋值运算符重载即可。
class NonCopy
{
private:
NonCopy(const NonCopy& nc) = delete;
NonCopy operator=(const NonCopy& nc) = delete;
};
实现方式:
1. 将类的构造函数私有,拷贝构造声明成私有。防止别人调用拷贝在栈上生成对象。
2. 提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建。
class HeapOnly
{
public:
static HeapOnly* CreateObject()
{
return new HeapOnly;
}
private:
HeapOnly() {}
// C++98
// 1.只声明,不实现。因为实现可能会很麻烦,而你本身不需要
// 2.声明成私有
HeapOnly(const HeapOnly& ho);
// C++11
HeapOnly(const HeapOnly&) = delete;
};
1.类似在堆上创建对象(拷贝构造不能禁)
class StackOnly
{
public:
static StackOnly CreateObject()
{
StackOnly obj;
return obj;
}
private:
HeapOnly() {}
};
问题:
StackOnly obj = StackOnly::CreateObj();
StackOnly* ptr3 = new StackOnly(obj);
拷贝构造没禁,依旧能够在堆上创建。、
2.自己写个类专属的operator new,屏蔽全局已有的operator new函数。
class B
{
public:
void* operator new(size_t size) = delete;
static B CreatB()
{
B bb;
return bb;
}
private:
B() = default;
};
// C++98中构造函数私有化,派生类中调不到基类的构造函数。则无法继承
class NonInherit
{
public:
static NonInherit GetInstance()
{
return NonInherit();
}
private:
NonInherit()
{}
};
C++11方法
final关键字,final修饰类,表示该类不能被继承。
class A final
{
// ....
};
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的
总结。
单例模式:
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个
访问它的全局访问点,该实例被所有程序模块共享。
就是说不管你将来用不用,程序启动时就创建一个唯一的实例对象。
class E
{
public:
static E* CreatE()
{
return ⅇ
}
void Add(const string& key, const string& value)
{
ms[key] = value;
}
void print()
{
for (auto kv : ms)
{
cout << kv.first << ":" << kv.second << endl;
}
}
private:
E() = default; //构造私有
//禁用拷贝和赋值
E(const E& ee) = delete;
E& operator=(const E& ee) = delete;
map ms;
//使全局只有一个E对象
static E ee;
};
E E::ee; // 在程序入口(main)之前就完成单例对象的初始化
void test()
{
E::CreatE()->Add("left", "左边");
E::CreatE()->Add("right", "右边");
E::CreatE()->Add("front", "前面");
E::CreatE()->print();
}
如果这个单例对象在多线程高并发环境下频繁使用,性能要求较高,那么显然使用饿汉模式来避
免资源竞争,提高响应速度更好。
第一次用的时候再创建。
class f
{
public:
static f* creatf()
{
if (ff == nullptr)
{
ff = new f;
}
return ff;
}
void add(const string& key, const string& value)
{
ms[key] = value;
}
void print()
{
for (auto kv : ms)
{
cout << kv.first << ":" << kv.second << endl;
}
}
/*如果要在程序结束前做些操作,如持久化操作(在结束前要求把数据写到文件),
那么就用gc类static对象解决(并且能解决new对象释放问题)*/
//
class gc
{
public:
~gc()
{
del();
}
};
static gc _gc;
//
static void del()
{
if (ff)
{
delete ff;
ff = nullptr;
}
}
private:
f() = default;
f(const f& ee) = delete;
f& operator=(const f& ee) = delete;
~F()
{
// 持久化:要求把数据写到文件
cout << "数据写到文件" << endl;
}
map ms;
static f* ff; //1.采取指针的形式实现用的时候创建,并且只能创建一次
};
f* f::ff = nullptr;
f::gc f::_gc;