成都网站制作培训市场营销策划方案范文
特殊类设计
- 1.设计类:不能被拷贝
- 2.设计类:不能被继承
- 3.设计类:只能在堆上创建对象
- 4.设计类:只能在栈上创建对象
- 5.设计类:只能创建一个对象(单例模式)
本节重点:
- 掌握特殊类的设计方式
1.设计类:不能被拷贝
// C++98私有化
class Copy
{
private:Copy(const Copy&);Copy& operator=(const Copy&);
};
// C++11关键字delete
class Copy
{
public:Copy(const Copy&) = delete;Copy& operator=(const Copy&) = delete;
};
2.设计类:不能被继承
// C++98中构造函数私有化, 派生类无法调用基类的构造函数, 无法继承
class NoInherit
{
public:static NoInherit GetInstance(){return NoInherit();}private:NoInherit(){}
};
// C++11关键字fianl
class NoInherit final
{// ...
};
3.设计类:只能在堆上创建对象
class HeapOnly
{
public:static HeapOnly* CreateObj(){return new HeapOnly();}// 禁用: 拷贝构造和拷贝赋值HeapOnly(const HeapOnly&) = delete;HeapOnly& operator=(const HeapOnly&) = delete;private:// 默认构造私有化HeapOnly(){}
};int main()
{// HeapOnly obj1;// static HeapOnly obj2;// HeapOnly *obj3 = new HeapOnly();HeapOnly* obj4 = HeapOnly::CreateObj();// HeapOnly obj5(*obj4);// HeapOnly obj6 = *obj4;delete obj4;return 0;
}
class HeapOnly
{
public:void Delete(){delete this;}
private:// 析构函数私有化~HeapOnly(){}
};int main()
{// 程序结束调用析构函数, 由于私有化, 无法创建对象 // HeapOnly obj1;// static HeapOnly obj2;// 可以在堆上创建对象, 但是调用delete存在问题(delete: 先调用析构函数, 再释放空间)// HeapOnly* obj3 = new HeapOnly();// delete obj3;HeapOnly *obj4 = new HeapOnly();obj4->Delete();return 0;
}
4.设计类:只能在栈上创建对象
class StackOnly
{
public:static StackOnly CreateObj(){return StackOnly();}void* operator new(size_t) = delete;void operator delete(void*) = delete;private:StackOnly(){}
};int main()
{// StackOnly obj1;// static StackOnly obj2;// StackOnly* obj3 = new StackOnly();// 传值返回需要拷贝构造StackOnly obj4 = StackOnly::CreateObj();StackOnly obj5(obj4);StackOnly obj6 = obj4;// 但是用拷贝构造创建堆区对象: 于是可以禁用new// StackOnly* obj7 = new StackOnly(obj4);// 问题: 静态区创建对象static StackOnly obj8(obj4);return 0;
}
class StackOnly
{
public:static StackOnly CreateObj(){return StackOnly();}// 禁用拷贝构造, 打开移动构造StackOnly(StackOnly&&){}StackOnly(const StackOnly&) = delete;private:StackOnly(){}
};int main()
{// StackOnly obj1;// static StackOnly obj2;// StackOnly* obj3 = new StackOnly();// 此时采用: 移动构造StackOnly obj4 = StackOnly::CreateObj();// StackOnly obj5(obj4);// StackOnly obj6 = obj4;// StackOnly* obj7 = new StackOnly(obj4);// static StackOnly obj8(obj4);// 问题: 移动构造创建对象static StackOnly obj8(move(obj4));StackOnly* obj9 = new StackOnly(move(obj4));return 0;
}
5.设计类:只能创建一个对象(单例模式)
- 设计模式:反复使用,多数人知晓、经过分类的、代码设计经验的总结。
- 单例模式:一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,这种方式简化了在复杂环境下的配置管理。
- 迭代器模式、适配器模式、单例模式、策略模式、观察者模式、工厂模式、装饰器模式等…
单例模式有两种实现模式:饿汉模式和懒汉模式
// 饿汉模式存在问题
// 1. 多个饿汉模式的单例,某个对象初始化内容较多(读文件),会导致程序启动慢
// 2. A和B两个饿汉,对象初始化存在依赖关系,要求A先初始化,B再初始化,无法保证
class InfoMar
{
public:static InfoMar& GetInstance(){return _ins;}private:InfoMar(){cout << "ip:" << _ip << endl;cout << "port: " << _port << endl;}// 禁用: 拷贝构造和拷贝赋值InfoMar(const InfoMar&) = delete;InfoMar& operator=(const InfoMar&) = delete;private:string _ip = "127.0.0.1";int _port = 8080;// 静态对象与普通对象不同: 不在类中, 而是在静态区, 类域的限制static InfoMar _ins;
};// 静态成员: 类内声明, 类外定义
InfoMar InfoMar::_ins;int main()
{// 程序运行在该行: 静态对象就被创建好了InfoMar::GetInstance();return 0;
}
// 懒汉模式: 解决饿汉模式的两个问题
class InfoMar
{
public:static InfoMar& GetInstance(){// 第一次调用时创建单例对象// 存在线程安全问题if (_pins == nullptr){_pins = new InfoMar;}return *_pins;}static void DelInstance(){delete _pins;_pins = nullptr;}private:InfoMar(){cout << "ip:" << _ip << endl;cout << "port: " << _port << endl;}// 禁用: 拷贝构造和拷贝赋值InfoMar(const InfoMar&) = delete;InfoMar& operator=(const InfoMar&) = delete;private:string _ip = "127.0.0.1";int _port = 8080;static InfoMar* _pins;
};InfoMar* InfoMar::_pins = nullptr;int main()
{InfoMar::GetInstance();return 0;
}// 懒汉模式2: 推荐
class InfoMar
{
public:static InfoMar& GetInstance(){// 局部静态: 再第一次调用时创建单例对象// C++11之后static InfoMar ins;return ins;}private:InfoMar(){cout << "ip:" << _ip << endl;cout << "port: " << _port << endl;}// 禁用: 拷贝构造和拷贝赋值InfoMar(const InfoMar&) = delete;InfoMar& operator=(const InfoMar&) = delete;private:string _ip = "127.0.0.1";int _port = 8080;
};int main()
{InfoMar::GetInstance();return 0;
}