当前位置: 首页 > news >正文

徐州建站服务网站建设属于哪类工作

徐州建站服务,网站建设属于哪类工作,陕西网站建设费用,液压产品做哪个网站好文章目录 1. 设计一个类, 不能被拷贝2. 设计一个类, 不能被继承3. 设计一个类, 只能在堆上创建对象3. 设计一个类, 只能在栈上创建对象4. 创建一个类, 只能创建一个对象(单例模式)饿汉模式懒汉模式 1. 设计一个类, 不能被拷贝 #x1f495; C98方式#xff1a; 在C11之前 C98方式 在C11之前想要一个一个类不被拷贝只有将拷贝构造函数定义为私有这样在类外就不能调用拷贝构造函数来构造对象了。但是在类内还是可以调用拷贝构造函数来构造对象。 所以正确的做法是 将拷贝构造函数定义为私有同时拷贝构造函数只声明不实现。这样即使在类中掉哦那个了拷贝构造函数编译器也会将错误检查出来。 class CopyBan { public:CopyBan(){_ptr new char[10]{ 0 };}~CopyBan(){delete[] _ptr;}void func(){CopyBan tmp(*this);}private:// 重写深拷贝构造函数CopyBan(const CopyBan cb);char* _ptr; };C11方式 C11扩展delete的用法delete除了释放new申请的资源外如果在默认成员函数后跟上delete表示让编译器删除掉该默认成员函数。 同时这种方法也不再需要将拷贝构造函数定义为私有。 class CopyBan { public:CopyBan(){_ptr new char[10]{ 0 };}~CopyBan(){delete[] _ptr;}CopyBan(const CopyBan cb) delete;private:char* _ptr; };2. 设计一个类, 不能被继承 C98方式 C98中构造函数私有化派生类中调不到基类的构造函数则无法调用父类的构造函数完成父类成员的初始化工作从而达到父类不能被继承的效果。 class NonInherit { public:static NonInherit GetInstance(){return NonInherit();} private:NonInherit(){} }; class subClass : public NonInherit { public:subClass(){} private:int _a 0; };C11方式 使用final关键字来修饰该类表示该类不能被继承 class NonInherit final { public:static NonInherit GetInstance(){return NonInherit();} private:NonInherit(){} };3. 设计一个类, 只能在堆上创建对象 一般的类可以在三个不同的存储位置创建对象 在栈上创建对象对象出了局部作用域自动销毁通过new关键字在堆上创建对象对象出了局部作用域不会自动销毁需要我们手动销毁。否则则会发生内存泄漏通过static关键字在静态区创建对象对象的作用域为定义时所在的局部域而对象的生命周期伴随着整个进程这个对象在mian调用结束后由操作系统自动回收 方法一构造函数私有化 将构造函数声明为私有同时删除拷贝构造函数然后提供一个静态成员函数在该静态成员函数中完成堆对象的创建。 class HeapOnly { public:static HeapOnly* CreateObj(){return new HeapOnly;}HeapOnly(const HeapOnly ho) delete; private:HeapOnly(){} };静态成员没有this指针所以可以通过类名域作用限定符来进行调用而不需要通过对象调用。同时我们还需要删除拷贝构造函数防止在类外通过下面这种取巧的方式来创建栈区或者堆区对象 HeapOnly* pho1 HeapOnly::CreateObj(); HeapOnly pho2(*pho1); // 通过拷贝构造函数在栈上创建对象 static HeapOnly ho3(*pho1); // 通过拷贝构造函数在静态区上创建对象方法二析构函数私有化 将析构函数私有化同时提供一个专门的成员函数在该成员函数中完成堆对象的析构 class HeapOnly { public:HeapOnly(){}void Destroy(){this-~HeapOnly();} private:~HeapOnly(){} };对于在堆上创建的对象编译器并不会主动调用析构函数来回收资源而是由用户手动进行delete或者进程退出后由操作系统回收所以编译器并不会报错。但对于自定义类型的对象delete会首先调用其析构函数完成兑现资源的清理然后再调用operator delete 释放对象的空间所以这里我们不能使用delete关键字来手动释放new出来的对象因为调用析构函数会失败。 所以我们需要一个Destroy成员函数通过它来调用析构函数完成资源的清理。这个Destroy函数不需要声明为静态类型因为只有类的对象才需要调用它。最后我们也不需要再删除拷贝构造函数了因为拷贝出来的栈对象或者静态对象压根儿无法创建出来。 3. 设计一个类, 只能在栈上创建对象 方法一在类中禁用operator new 和 operator delete函数 new和delete是C中的关键字其底层通过调用operator new 和operator delete函数来开辟和释放空间。 operator new 和 operator delete 函数是普通的全局函数而并非运算符重载它们的函数名就长这样罢了。因此我们可以在类中重载operator new和 operator delete 函数然后将他们声明为删除函数这样就不能通过new和delete再堆上创建对象了但是我们仍然可以在静态区创建对象与类的要求不符。 class StackOnly { public:StackOnly(int x 0):_x(x){}~StackOnly(){}void* operator new(size_t size) delete;void operator delete(void* p) delete; private:int _x; };方法二构造函数私有化提供一个在栈上创建对象的静态成员函数 这种方式和设计一个 只能在堆上创建对象的类的思路是一样的。但是不能删除拷贝构造函数否则就不能通过下面这种方式构造栈对象了。 StackOnly st StackOnly::CreateObj(); 但是不禁用拷贝构造函数又会导致可以通过拷贝构造函数创建出静态区上的对象所以我们设计出的只能在栈上创建对象的类是有缺陷的。 class StackOnly { public:static StackOnly CreateObj(int x){return StackOnly(x);} private:StackOnly(int x 0):_x(x){}int _x; };int main() {StackOnly st1 StackOnly::CreateObj(1);return 0; }4. 创建一个类, 只能创建一个对象(单例模式) 设计模式Design Pattern 是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。为什么会产生设计模式这样的东西呢就像人类历史发展会产生兵法。最开始部落之间打仗时都是人拼人的对砍。后来春秋战国时期七国之间经常打仗就发现打仗也是有套路的后来孙子就总结出了《孙子兵法》。孙子兵法也是类似。 使用设计模式的目的为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化设计模式是软件工程的基石脉络如同大厦的结构一样。 单例模式 一个类只能创建一个对象即单例模式该模式可以保证系统中该类只有一个实例并提供一个访问它的全局访问点该实例被所有程序模块共享。比如在某个服务器程序中该服务器的配置信息存放在一个文件中这些配置数据由一个单例对象统一读取然后服务进程中的其他对象再通过这个单例对象获取这些配置信息这种方式简化了在复杂环境下的配置管理。 单例模式有两种实现模式饿汉模式和懒汉模式。 饿汉模式 饿汉模式是将构造函数私有然后删除拷贝构造函数和赋值运算符重载函数由于单例模式全局只允许有一个唯一对象所以我们可以定义一个静态类对象作为类的承运然后提供一个GetInstance接口来获取这个静态类对象。静态类对象需要在类内声明类外定义定义时需要指定类域。同时GetInstance接口也必须是静态函数。 饿汉模式的特点是在类加载的时候就创建单例对象因此其实梨花在程序运行之前main函数调用之前就已经完成实现如下 class Singleton { public:static Singleton* GetInstance(){return _ins;}Singleton(const Singleton s) delete;Singleton operator(const Singleton s) delete;private:// 限制在类外面随意创建对象Singleton(){}static Singleton* _ins; };Singleton* Singleton::_ins new Singleton;因为饿汉模式在main函数前就被创建所以它不存在线程安全问题但是它也存在一些缺点 有的单例对象构造十分耗时或者需要占用很多资源比如加载插件、 初始化网络连接、读取文件等等会导致程序启动时加载速度慢。饿汉模式在程序启动时就创建了单例对象所以即使在程序运行期间并没有用到该对象它也会一直存在于内存中浪费了一定的系统资源。多个单例类存在初始化依赖关系时饿汉模式无法控制。比如A、B两个单例类存在于不同的文件中我们要求先初始化A再初始化B但是A、B谁先启动初始化是由OS自动进行调度控制的我们无法进行控制。 多线程模式下的饿汉模式 class Singleton { public:static Singleton* GetInstance(){return _ins;}void Add(const string str){_mtx.lock();_v.push_back(str);_mtx.unlock();}void Print(){_mtx.lock();for (auto e : _v)cout e endl;cout endl;_mtx.unlock();}Singleton(const Singleton s) delete;Singleton operator(const Singleton s) delete;private:// 限制在类外面随意创建对象Singleton(){}vectorstring _v;static Singleton* _ins;mutex _mtx; };Singleton* Singleton::_ins new Singleton;int main() {srand(time(0));int n 100;thread t1([n]() {for (size_t i 0; i n; i){Singleton::GetInstance()-Add(t1线程: to_string(rand()));}});thread t2([n]() {for (size_t i 0; i n; i){Singleton::GetInstance()-Add(t2线程: to_string(rand()));}});t1.join();t2.join();Singleton::GetInstance()-Print();return 0; }懒汉模式 如果单例对象构造十分耗时或者占用很多资源比如加载插件啊 初始化网络连接啊读取文件啊等等而有可能该对象程序运行时不会用到那么也要在程序一开始就进行初始化就会导致程序启动时非常的缓慢。 所以这种情况使用 懒汉模式延迟加载更好。 懒汉模式 是另一种实现单例模式的方式与饿汉模式不同的是懒汉模式是延迟示例化的即在第一次访问时才创建唯一的实例。 懒汉模式的实现思路是将构造函数私有化然后提供一个静态私有指针成员来保存唯一实例的地址并通过一个公共的静态方法来获取该实例。 class Singleton { public:static Singleton GetInstance(){// 双检查加锁if (_ins nullptr){_smtx.lock();if(_ins nullptr)_ins new Singleton;_smtx.unlock();}return *_ins;}static void DelInstance(){_smtx.lock();if (_ins) {delete _ins;_ins nullptr;}_smtx.unlock();}Singleton(const Singleton s) delete;Singleton operator(const Singleton s) delete;~Singleton(){// 持久化// 比如要求程序结束时将数据写到文件单例对象析构时持久化就比较好} private:// 限制在类外面随意创建对象Singleton(){}static Singleton* _ins;static mutex _smtx; };Singleton* Singleton::_ins nullptr; mutex Singleton::_smtx;懒汉模式下的线程安全问题以及双检查加锁 懒汉模式也引入了新的问题单例对象的创建线程是不安全的。对于懒汉模式来说由于其单例对象是在第一次使用时才创建的那么在多线程模式下就有可能会存在多个线程并行/并发的去执行 _psins new Singleton 语句从而导致前面创建出来单例对象指针被后面的覆盖最终发生内存泄露。 单例对象的资源释放与保存问题 一般来说单例对象都是不需要考虑释放的因为不管是饿汉模式还是懒汉模式单例对象都是全局的全局资源在程序结束后会被自动回收 (进程退出后OS会解除进程地址空间与物理内存的映射)。但是我们也可以手动对其进行回收。需要注意的是有时我们需要在回收资源之前将资源的相关数据保存到文件中这种情况下我们就必须手动回收了。 在类中定义一个静态的 DelInstance接口来回收与保存资源。 static void DelInstance() {_smtx.lock();if (_ins) {delete _ins;_ins nullptr;}_smtx.unlock(); }定义一个内部的GC类通过Singleton类中的一个静态GC类对象使得程序在结束回收GC对象时自动调用GC类的析构从而完成资源回收与数据保存工作。避免我们忘记调用Dellnstance接口而丢失数据。 例如 class Singleton { public:static Singleton GetInstance(){if (_ins nullptr){// 双检查加锁_smtx.lock();if(_ins nullptr)_ins new Singleton;_smtx.unlock();}return *_ins;}void Add(const string str){_mtx.lock();_v.push_back(str);_mtx.unlock();}void Print(){_mtx.lock();for (auto e : _v)cout e endl;cout endl;_mtx.unlock();}static void DelInstance(){_smtx.lock();if (_ins) {delete _ins;_ins nullptr;}_smtx.unlock();}// 单例对象回收class GC{public:~GC(){DelInstance();}};static GC _gc;Singleton(const Singleton s) delete;Singleton operator(const Singleton s) delete;~Singleton(){// 持久化// 比如要求程序结束时将数据写到文件单例对象析构时持久化就比较好} private:// 限制在类外面随意创建对象Singleton(){}vectorstring _v;static Singleton* _ins;mutex _mtx;static mutex _smtx; };Singleton* Singleton::_ins nullptr; mutex Singleton::_smtx; Singleton::GC Singleton::_gc;懒汉模式的一种简单实现方式 class Singleton { public:static Singleton GetInstance(){static Singleton sins;return sins;}Singleton(const Singleton sin) delete;Singleton operator(const Singleton sin) delete; private:Singleton(){} };上面这种实现方式的缺点就是不稳定因为只有在 C11 及其之后的标准中局部静态对象的初始化才是线程安全的而在 C11 之前的版本中并不能保证。
http://www.ho-use.cn/article/10818063.html

相关文章:

  • 如何看网站有没有备案网站安全防黑联盟
  • 做响应式网站设计师需要做什么丰顺最新新闻今天
  • 视频网站开发公司游戏开发引擎
  • 阿里云网站备案多少天wordpress页面相册
  • 权威的网站建设公司广州网站推广模板
  • 浪潮云网站建设校园类网站模板
  • 临沂做过网站的公司辽宁省建设安全监督网网站
  • 做网站开发的需求文档怎样建立自己的微信公众号
  • 怎么做外贸网站推广网站建设中的形象满意指的是销售
  • 做pc端网站行情写出电子商务网站的建设流程
  • 许昌工程建设信息网站人才网官网登录
  • 网页具有动画网站建设技术wordpress页面模版放在那个文件夹
  • 自己做网站可以赚钱么装wordpress需要配置apache
  • 怎样做淘宝联盟的网站建设网站资料在哪收集
  • seo站外推广动态asp.net网站开发教程
  • 淮北市建设局网站盈利网站备案
  • 网站建设外包注意事项学校网站建设开题报告
  • congqin网站建设简约大方网站
  • 网站建设趋势那些市区做网站群
  • 国外大学网站建设比较网站会员注册模板
  • 创办网站的步骤广东百度推广的代理商
  • 建设网站应注意什么网站还建设 域名可以备案吗
  • 婚庆网页设计作品dwseo如何优化
  • php自己做网站吗网站建设项目意义
  • 长治网站制作小程序ui交互设计作品
  • 建设公司网站法律声明网站开发职业工资
  • 网站域名ip地址查询天津网站优化步骤
  • app推荐网站网站如何做图片自动切换
  • 网上营销型网站建设官方网站请示
  • 虚拟主机 部署网站吗电脑网址打不开网页怎么办