C++ 第五篇
5.1 静态成员(static)
5.1.1. 静态成员变量
1) 语法
class 类名{
static 数据类型 变量名;// 声明
/
const static 数据类型 变量名 = 初值;//特殊变量
/
}
数据类型 类名::变量名= 初值; // 定义和初始化
2) 普通成员变量属于对象。静态成员变量不属于对象
3) 普通成员变量在构造对象的时候定义和初始化,但是静态成员变量需要在类的外部单独定义和初始化。
4) 静态成员变量和全局变量类似,被放在数据段(全局区),可以把静态成员变量理解访问被限制在类中使用的全局变量。
5) 使用:
类名::静态成员变量; // 推荐
对象.静态成员变量 // 本质和上面等价
6) 如果同时被const 和static 修饰的成员变量,需要在声明时就进行初始化。
5.1.2. 静态成员函数
1) 语法
class 类名{
static 返回类型 函数名(形参表){…}// 声明
};
2) 静态成员函数没有this 指针,也没有const 属性,可以把他理解为被限制在类中使用的全局函数。
3)使用
类名::静态成员函数(实参表); // 推荐
对象名.静态成员函数(实参表); // 不推荐 与普通成员函数容易混淆
4) 静态成员函数中只能访问静态成员;而非金泰成员函数中既可以方位静态成员,也可以访问非静态成员。
5.2 单例模式
1) 概念: 一个类只允许存在唯一的对象,并提供他的访问方法。
2) 实现方式
- 禁止在类的外部创建对象: 私有化构造函数(包括拷贝构造)
- 类的内部维护唯一的对象: 静态成员变量
- 提供访问单例对象的方法: 静态成员函数
3) 创建方法
-
饿汉式: 单例对象无论用或者不用,程序启动即创建
优点:代码实现简单,访问效率高、多线程安全
缺点:浪费内存, -
懒汉式: 单例对象用时再创建,不用即销毁
优点:节省内存
缺点:访问效率低,代码实现复杂,多线程需要加锁保护
饿汉式:
#include <iostream>
using namespace std;
class Singleton {
public:
// 3. 静态成员函数
static Singleton& get_instance(void)
{
return s_instance;
}
void print() const {
cout << m_data << endl;
}
//1. 私有化构造函数(普通构造和拷贝构造函数)
private:
Singleton(int data):m_data(data)
{
cout<<"object has been created" << endl;
}
Singleton(const Singleton & );
// 2. 静态成员变量维护唯一的对象
static Singleton s_instance;
int m_data;
};
Singleton Singleton::s_instance = 123;
int main(void)
{
cout << "main has been running" << endl;
//Singleton s1 = Singleton::get_instance(); // error
Singleton& s1 = Singleton::get_instance();
Singleton& s2 = Singleton::get_instance();
Singleton& s3 = Singleton::get_instance();
s1.print();
cout <<"&s1=" << &s1 << endl;
cout <<"&s2=" << &s2 << endl;
cout <<"&s3=" << &s3 << endl;
cout << "main function end " << endl;
}
运行结果:
object has been created
main has been running
123
&s1=0x601194
&s2=0x601194
&s3=0x601194
main function end
- 懒汉式:
#include <iostream>
#include <pthread.h>
using namespace std;
class Singleton {
public:
static Singleton& get_instance(int data)
{
pthread_mutex_lock(&singleton_mutex); // 添加互斥锁,防止多线程操作 出现并发错误
if (s_instance == NULL){
s_instance = new Singleton(123);
}
++ m_counter;
pthread_mutex_unlock(&singleton_mutex);
return *s_instance;
}
void release(void) // 添加release函数,使用后释放该对象
{
pthread_mutex_lock(&singleton_mutex);
if (--m_counter == 0 ){ // 只有引用数为0时,才会被真正释放
delete s_instance;
s_instance = NULL;
}
pthread_mutex_unlock(&singleton_mutex);
}
void print() const {
cout << m_data << endl;
}
private:
Singleton(int data):m_data(data)
{
cout<<"object has been created" << endl;
}
Singleton(const Singleton & );
~Singleton()
{
cout <<"object has benn release"<< endl;
}
static Singleton* s_instance;
static int m_counter; // 添加counter 来标记该对象被引用的次数
static pthread_mutex_t singleton_mutex;
int m_data;
};
Singleton* Singleton::s_instance = NULL; // 实例对象初始化为空指针,此时没有实例对象
int Singleton::m_counter = 0;
pthread_mutex_t Singleton::singleton_mutex = PTHREAD_MUTEX_INITIALIZER;
int main(void)
{
cout << "main has been running" << endl;
// Singleton s1 = Singleton::get_instance(); // error
Singleton& s1 = Singleton::get_instance(123);
Singleton& s2 = Singleton::get_instance(123);
Singleton& s3 = Singleton::get_instance(123);
s1.print();
cout <<"&s1=" << &s1 << endl;
cout <<"&s2=" << &s2 << endl;
cout <<"&s3=" << &s3 << endl;
s1.release();
s2.release();
s3.release();
cout << "main function end " << endl;
}