毕业设计网站怎么做,网站建设推广是什么,500云空间网站,青岛网站建设服务器目录 引言
1.请设计一个类#xff0c;不能被拷贝
2. 请设计一个类#xff0c;只能在堆上创建对象
为什么设置实例的方法为静态成员呢
3. 请设计一个类#xff0c;只能在栈上创建对象
4. 请设计一个类#xff0c;不能被继承 5. 请设计一个类#xff0c;只能创建一个对…目录 引言
1.请设计一个类不能被拷贝
2. 请设计一个类只能在堆上创建对象
为什么设置实例的方法为静态成员呢
3. 请设计一个类只能在栈上创建对象
4. 请设计一个类不能被继承 5. 请设计一个类只能创建一个对象(单例模式)
饿汉模式
懒汉模式
单例对象一般不考虑析构
为什么私有析构呢 引言
在当今的软件开发实践中特殊类设计模式扮演着至关重要的角色它们不仅提高了代码的可维护性和可扩展性还确保了系统的稳定性和性能。其中单例模式作为最常用的设计模式之一以其独特的实例管理方式成为了许多场景下的首选解决方案。本文旨在探讨C中单例模式及其他特殊类设计的精髓通过分析其背后的设计哲学和实现技巧帮助读者掌握这些高级编程技巧以提升其在软件开发过程中的设计能力和代码质量。 在我们设计一个特殊类的时候一般要把构造、拷贝和赋值私有保护防止被其他类拷贝或者产生不想要意料之外的错误。
1.请设计一个类不能被拷贝
拷贝只会放生在两个场景中拷贝构造函数以及赋值运算符重载因此想要让一个类禁止拷贝 只需让该类不能调用拷贝构造函数以及赋值运算符重载即可 。 C98 将拷贝构造函数与赋值运算符重载只声明不定义并且将其访问权限设置为私有即可。 class CopyBan
{// ...private:CopyBan(const CopyBan);CopyBan operator(const CopyBan);//...
};C11 C11扩展delete的用法delete除了释放new申请的资源外如果在默认成员函数后跟上 delete表示让编译器删除掉该默认成员函数。 class CopyBan
{// ...CopyBan(const CopyBan)delete;CopyBan operator(const CopyBan)delete;//...
}; 同时我们还可以设置一个基类让子类继承基类让子类正常实现功能设置基类不可被拷贝即可。 2. 请设计一个类只能在堆上创建对象 实现方式 1. 将类的构造函数私有拷贝构造声明成私有。防止别人调用拷贝在栈上生成对象。 2. 提供一个静态的成员函数在该静态成员函数中完成堆对象的创建。 只能在堆上创建对象即只能new对象不允许在栈上创建临时变量。当然要禁用拷贝、构造、赋值函数非单例 class HeapOnly
{
public: static HeapOnly* CreateObject() { return new HeapOnly; }
private: HeapOnly() {}// C98// 1.只声明,不实现。因为实现可能会很麻烦而你本身不需要// 2.声明成私有HeapOnly(const HeapOnly)// or// C11 HeapOnly(const HeapOnly) delete;
} 由于没有this指针无法调用构造而是只是去new这个镀锡由系统去完成资源的申请 静态不能调用非静态就是因为没有this指针缺少调用的参数 但是new和delete这种操作不需要this指针 那每次调的时候返回的都是一个新的静态对象吗--- NO这个方法是静态的但是返回的变量不是静态的 为什么设置实例的方法为静态成员呢 收线确定的是一定是内部new创建的对象。 因为如果设置为非静态成员那就只能通过对象去调用但是我们不能去在栈区创建对象。 并且构造私有外部一定不可以创建对象只能用类调用所以必须静态 为什么禁用拷贝构造比如A a1(a2)这样a1依然是在栈区 3. 请设计一个类只能在栈上创建对象 只能通过类型创建禁止new对象 方法一同上将构造函数私有化然后设计静态方法创建对象返回即可 依然需要把构造私有需要注意的是不能把构造和拷贝工构造私有 class StackOnly
{
public:static StackOnly CreateObj(){StackOnly obj;return obj;}void* operator new(size_t size) delete;void operator delete(void* p) delete;
private:StackOnly() :_a(0){}
private:int _a;
}; 1.设置为静态 并且构造私有外部一定不可以创建对象只能用类调用所以必须静态 2.为什么不可以禁用拷贝构造比如A a1(a2)这样a1依然是在栈区符合要求并且匿名对象的声明周期只在这一行为了防止匿名对象周期太短无法进行较好的连续性开发所以需要赋值给另一个栈区的对象。 3.可以返回临时对象只需要赋值给其他对象即可栈区也可以返回非匿名对象也是采用赋值的方式进行连续性开发。 4.为了防止创建堆区对象需要禁用new和delete为了防止创建栈区对象时需要禁用拷贝、赋值 4. 请设计一个类不能被继承 C98方式 // C98中构造函数私有化派生类中调不到基类的构造函数。则无法继承
class NonInherit
{
public:static NonInherit GetInstance(){return NonInherit();}
private:NonInherit(){}
}; C11方法 final关键字 final修饰类表示该类不能被继承。 class A final
{// ....
}; 5. 请设计一个类只能创建一个对象(单例模式) 设计模式 设计模式Design Pattern是一套 被反复使用、多数人知晓的、经过分类的、代码设计经验的 总结。为什么会产生设计模式这样的东西呢就像人类历史发展会产生兵法。最开始部落之间打 仗时都是人拼人的对砍。后来春秋战国时期七国之间经常打仗就发现打仗也是有 套路的后 来孙子就总结出了《孙子兵法》。孙子兵法也是类似。 使用设计模式的目的为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模 式使代码编写真正工程化设计模式是软件工程的基石脉络如同大厦的结构一样。 单例模式 一个类只能创建一个对象即单例模式该模式可以保证系统中该类只有一个实例并提供一个 访问它的全局访问点该实例被所有程序模块共享。比如在某个服务器程序中该服务器的配置 信息存放在一个文件中这些配置数据由一个单例对象统一读取然后服务进程中的其他对象再 通过这个单例对象获取这些配置信息这种方式简化了在复杂环境下的配置管理。 单例模式有两种实现模式 饿汉模式 饿汉模式已经饿得不行了要求立刻有东西吃即在main函数之前就得创建好---全局 饿汉设置为全局提前创建。 既然是单例一定先把构造私有。 在类的外部虽然不能创建全局的对象但是在类的内部可以创建。----思路类的内部声明静态成员类的外部定义这样就是一个全局的数据。 demo // 懒汉模式第一次用的时候再创建现吃现做
class A {
public:static A* GetInstance() {return _inst;}
private:A() {}mapstring, string _dict;int _n 0;static A* _inst;
}; 我们在类的内部创建对象的时候当然不能 class A A _a 这样属于嵌套定义。 但是也不能内部用静态成员方法去获取因为函数需要在主函数内调用。 当我们在内部使用静态成员的时候当然不是嵌套定义因为静态不属于某个对象而是属于整个类。并且我们只能是在类内声明并没有定义需要在类的外部定义。 在类的外部定义的时候只需要点名类型 作用域即可不需要再次声明静态静态只需要声明一次即可但是定义实例化必须使用类型。 当需要使用这个实例的时候调用实例方法去获取即可。 总结 1.类内声明静态类外实例化静态全局 2.类内提供获取实例的犯法 同时删除拷贝构造和赋值 访问成员需要借助对象这时候就需要调用GetInstance函数 优点创建简单
缺点1.进程启动慢 2.一旦存在两个全局单例不能控制单例启动的先后顺序。 懒汉模式
现吃现做不着急main函数内创建。 只需要把静态的对象换成指针即可获取实例的时候如果指针是nullptr那么创建如果不是那么直接返回 线程不安全两个线程同时进来可能会new两个对象---加锁 单例对象一般不考虑析构
恶汉不存在释放的问题--全局
懒汉对象也一般不需要释放---单例对象一般是生命周期伴随整个程序对整个程序都起到至关重要的作用进程结束时会自动释放。 就算要释放如果我们期望既可以手动释放析构不能手动释放也可以在main函数结束时自动释放 class B
{
public:static B* GetInstance(){if (_inst nullptr){_inst new B;}return _inst;}static void DelInstance(){if (_inst){delete _inst;_inst nullptr;}}private:B(){}~B(){// 持久化要求把数据写到文件cout 数据写到文件 endl;}B(const B aa) delete;B operator(const B aa) delete;mapstring, string _dict;int _n 0;static B* _inst;class gc{public:~gc(){DelInstance();}};static gc _gc;
};B* B::_inst nullptr;
B::gc B::_gc;
可以私有析构函数
提供一个调用析构函数的接口DelInstance我们可以手动调用这个接口去进行析构。 我们新建一个内部类这个内部类是外部类的友元可以访问私有。等main函数结束的时候_gc调用析构析构会调用DelInstance。
这样可以做到1.显示释放析构不允许显示调用但是delete指针的时候可以调用析构 2.没有显示释放等程序结束也会释放 为什么私有析构呢
B* instance B::GetInstance(); delete instance;
B* instance2 B::GetInstance();
如果是public的话每个人可以自己delete这个那么就违背单例模式的原则了
而这块放的这个DelInstance函数是意思万一情况下不使用单例了自己想释放的话可以通过这个函数释放但是一般也不会这样做的一般gc就替咱们回收了
总之就是不能让其他人去随便delete单例所以私有同时希望gc能够管理单例等程序结束gc清理的时候gc会协助清理单例