一、静态成员
Ⅰ.什么是静态成员:
被static修饰的成员变量和成员函数就叫静态成员
Ⅱ.普通成员的特点:
-
成员变量:每个类对象中都有一份属于自己的成员变量,相互之间没有关联、独立的
-
成员函数:隐藏着一个this指针,接收调用者的地址用于区分调用者
Ⅲ.静态成员的特点:
-
静态成员变量:
①存储在data或bss内存段中,一个类中的所有静态成员变量只有唯一一份,被所有类对象共享
②一旦成员变量被声明为静态成员变量后,通过sizeof计算类字节数时,就不统计该变量的字节数
③静态成员变量必须在类内加static声明,在类外单独定义、初始化,定义时无需加static
④静态成员变量的生命周期不再依赖于某个对象,伴随整个程序的生命周期
⑤因为静态成员变量的存在不依赖于任何类对象,所以可以无需实例化类对象,直接访问静态成员变量类名::静态成员变量 (无需实例化对象,但是一般成员变量都是私有的) 对象名.成员变量/静态成员变量 对象名.成员变量/静态成员变量
-
静态成员函数:
①没有隐藏的this指针,所以在静态成员函数中无法直接访问普通成员变量、普通成员函数,但是可以手动传递对象的地址来间接访问,毕竟静态成员函数还是属于类的
②但是可以直接访问静态成员变量、静态成员函数
③调用方式类名::静态成员函数() (无需实例化对象) 对象名.成员函数()/静态成员函数() 对象名.成员函数()/静态成员函数()
Ⅳ.静态成员的作用
-
静态成员相当于多了一层类作用域的全局变量、全局函数
-
静态成员变量适合存储所有类对象的公共属性,从而节约资源(税率、利率等)
-
静态成员函数可以当做访问私有的静态成员变量的公开接口,一方面不破坏类的封装性,另一方面可以无需实例化对象也能调用类的静态成员,让类本身具有管理自己成员的能力
常见面试题
- C和C++中的static的区别?
二、单例模式(考点)
-
什么是单例模式:
只能实例化一个类对象 -
什么场景下使用单例模式:
进程管理器、日志管理器、网站访问计数器、应用配置程序、线程池、服务器的连接管理器
Ⅰ.实现单例模式的原理:
-
禁止在类外随意实例化对象,把构造函数\拷贝构造私有化
-
确保类对象只有一份,在类中定义一个静态的类对象成员变量
-
提供一个获取静态类对象成员变量的公开的接口,设计一个静态成员函数用于获取那唯一的一个静态类对象
Ⅱ.饿汉模式的单例:(背)
-
程序运行开始时就立即实例化单例类对象,不管后期是否用得到都会完成实例化
-
优点:不可能被多个线程同时运行创建多份(线程安全)
-
缺点:如果后期使用不到,就浪费时间、资源
Ⅲ.懒汉模式的单例:(背)
-
什么时候使用,什么时候才去实例化单例类对象
-
优点:使用时才会创建,节约时间、资源
-
缺点:可能会被多个线程同时实例化,有可能会创建出多个单例类对象(线程不安全)
常考笔试题:实现饿汉、懒汉模式的单例,线程安全的懒汉模式的单例
-
饿汉单例模式
#include <iostream> using namespace std;class Single { static Single obj; Single(void) { cout << "我是构造函数" << endl; } Single(const Single& that) { cout << "我是拷贝构造" << endl; } public: static Single& getobj(void) { return obj; } void show(void) { cout << &obj << endl; } }; Single Single::obj; int main(int argc,const char* argv[]) { Single& s = Single::getobj(); s.show(); Single& s1 = Single::getobj(); s1.show(); }
-
懒汉单例模式
#include <iostream> using namespace std; class Single { static Single* obj; Single(void) { cout << "我是构造函数" << endl; } Single(const Single& that) { cout << "我是拷贝构造" << endl; } public: static Single& getobj(void) { if(obj == NULL) { obj = new Single; } return *obj; } void show(void) { cout << &obj << endl; } }; Single* Single::obj; int main(int argc,const char* argv[]) { Single& s = Single::getobj(); s.show(); Single& s1 = Single::getobj(); s1.show(); }
-
线程安全的懒汉单例模式
#include <iostream> #include <pthread.h> using namespace std; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; class Single { static Single* obj; Single(void) { cout << "我是构造函数" << endl; } Single(const Single& that) { cout << "我是拷贝构造" << endl; } public: static Single& get_obj(void) { if(NULL == obj) { obj = new Single; } return *obj; } void show(void) { cout << obj << endl; } }; Single* Single::obj; void* run(void* arg) { pthread_mutex_lock(&mutex); Single& s = Single::get_obj(); pthread_mutex_unlock(&mutex); } int main(int argc,const char* argv[]) { pthread_t tid[20]; for(int i=0; i<20; i++) { pthread_create(&tid[i],NULL,run,NULL); } for(int i=0; i<20; i++) { pthread_join(tid[i],NULL); } }