【概念】代码的一些写法:程序灵活,维护方便;但代码晦涩,不易于别人接手。 2. 单例设计模式
【概念】:整个项目中,有某个或某些特殊的类,属于该类的对象,只能被创建1个。 3. 单例设计模式共享数据分析及解决
!!!单例模式的具体内容还应该参考 该链接,这里讲的更加详细和准确。本文的作者只讲解了双重锁定,而实际上该方法也已经被弃用,由于某些不安全因素,因此该链接中给出了更加合理的方法。 3.1 建议
建议在多线程中,将单例类在主线程中提前定义并初始化相关静态变量。如果对单例类中变量只读,则只读的共享数据不需要加锁。如果:需要在子线程中创建单例类对象,这种线程且不止一个,则会出现撞上初始化被多次执行。解决方法:增加互斥量
//.cpp //类的私有静态变量外部可以直接调用?? std::mu_tex my_tex; //线程入口函数 void my_thread(){ A* my_a=A::getInstance(); //... } class A{ public: static A * getInstance(){ if (my_instance==NULL){//方法二,双重锁定 unique_lockthread_mutex(my_tex);//方法一,效率低,解决不同线程撞上同样初始化 if(my_instance==nullptr){ my_instance=new A(); static My_garbage gb;//调用该类的析构函数时,顺势把new的my_instance删除掉。 } } return my_instance; } private: static A *my_instance; A();//!私有化构造函数,即全局只能有一个该类。 ~A(); }; class My_garbage{ //!!!巧妙设计,可以delete掉未知的new 变量。 public: My_garbage(){}; ~My_garbage(){ if(A::my_instance){ delete A::my_instance; A::my_instance=nullptr; } } }; //*******************.h //类静态变量初始化 A *A::my_instance==nullptr; A::A(){} A::~A(){} A::test(){ cout<<"test"< 4. call_once() 函数模板
c++引入的函数,该函数第二个参数是一个函数某名a();
!!!call_once()功能能够保证函数a()只被调用一次。不管有若干个线程调用该函数。
call_once具备互斥量这种能力,且效率上,比互斥量消耗的资源更少。
需要与标记结合使用,标记为 std::once_flag; 其实once_flag为一个结构。
call_once就是通过这个标记来决定对应的函数a()是否执行,调用call_once成功后,call_once就把标记设置为已调用状态,后续再次调用,那么对应的函数a()就不会再被执行了。
利用call_once来实现单例模式
std::once_flag my_flag;//系统定义的标记 //... class A{ private: static A* my_instance; A(){} public: static void creatInstance(){ //该函数只被调用一次 my_instance=new A(); static my_garbage my_g; } static A* getInstance(){ //该方法,每次都要通过call_once判断my_instance是否已经被定义。 call_once(my_flag,creatInstance()); return my_instance; } };四、补充 静态变量与局部变量区别(1)所有全局变量都是静态变量;而局部变量只有定义时加上类型修饰符static,才为局部静态变量。(2)静态变量不是说其值保持不变,其拥有的是值是可变的。说其静态,是因为其不会随着函数
调用和退出而发生变化,即上次调用函数的时候,如果我们给静态变量赋予某个值,下次函数调用的时,
这个值保持不变。(3)静态局部变量与auto自动变量的区别全局变量与局部变量的区别3.1 两者均是只能在函数内部使用,出了函数不能再使用;但是auto自动变量会随着函数退出而消失,static局部变量会一直存在,但在函数外部不能使用,
只能再次调用该函数时,它保留上次调用时的值,并可以继续使用。3.2 static变量初始化语句只需在第一次调用时使用;auto变量每次函数调用都会重新初始化。3.3 static变量初始化必须是常量或常量表达式,如果定义时没有赋值,系统会自动赋初值0(数值型变量为0,字符型为字符变量);
auto变量不赋初值,其值将会是一个不确定的值。3.4 当多次调用一个函数且要求在调用之间保持某些变量的值时,考虑采用静态局部变量。
虽然全局变量也可达到上述目的,但全局变量会造成意外的副作用,建议还是局部静态变量。3.5 局部静态变量占用内存时间较长,可读性差,非必要,避免使用。(1)作用域不同:全局变量作用域为整个程序;局部变量作用域为当前函数或者循环。(2)内存存储方式不同:全局变量存储在全局数据区中,局部变量存储在栈区。(3)生命周期不同:全局变量的生命期和主程序一样,随程序的销毁而销毁;局部变量在函数内部或
循环内部,随函数退出或循环退出而销毁。(4)使用方式不同:全局变量声明后程序的各个部分都可以用到,但是局部变量只能局部使用,
函数内部会优先使用局部变量再使用全局变量。欢迎分享,转载请注明来源:内存溢出
评论列表(0条)