C++静态成员变量及函数

简介: C++静态成员变量及函数

一、静态成员变量


1、普通成员变量属于对象,每个对象都会包含一份独立的普通成员变量;而静态成员变量不属于对象,一个类中静态成员变量只有一份


2、静态成员变量不能在构造函数中定义和初始化,需要在类的外部单独的定义和初始化。


3、静态成员变量和全局变量类似,被放在数据段,可以把静态成员变量理解为被限制在类中使用的全局变量.


4、访问静态成员变量方法:


   类名::静态成员变量;//推荐


   对象.静态成员变量;//本质和上面一样


#include <iostream>
using namespace std;
class A{
public:
    //普通成员变量在构造定义和初始化
    A(int data):m_data(data){}
    int m_data;//普通成员变量
    static int s_data;//静态成员变量
};
//静态成员变量需要在类的外部单独定义和初始化
int A::s_data = 20;
int main(void)
{
    A a(10);
    cout << "sizeof(a)=" << sizeof(a) << endl;
    //普通成员变量必须通过对象访问
    cout << a.m_data << endl;//10
    //静态成员变量可以通过"类名::"访问
    cout << A::s_data << endl;//20
    cout << a.s_data << endl;//ok,20
    A a2(10);
    a2.m_data = 100;
    a2.s_data = 100;
    cout << a.m_data << endl;//10
    cout << a.s_data << endl;//100
    return 0;
}


二、静态成员函数


1、静态成员函数中没有this,也没有const属性,可以把静态成员函数理解为被限制在类中使用的全局函数


2、使用方法:


   类名::静态成员函数(实参表);//推荐


   对象.静态成员函数(实参表);//本质和上面等价


3、在静态成员函数中只能访问静态成员,在非静态成员函数中既可以访问静态成员,也可以访问非静态成员


#include <iostream>
using namespace std;
class A{
public:
    //普通成员变量在构造定义和初始化
    A(int data):m_data(data){}
   
    static void func1(void){
        cout << "静态成员函数" << endl;
        //cout << m_data << endl;
        cout << s_data << endl;
    }
    void func2(void){
        cout << "非静态成员函数" << endl;
        cout << m_data << endl;
        cout << s_data << endl;
    }
    int m_data;//普通成员变量
    static int s_data;//静态成员变量
};
//静态成员变量需要在类的外部单独定义和初始化
int A::s_data = 20;
int main(void)
{
    A::func1();
    A a(10);
    a.func2();
    return 0;
}


三、单例模式


一个类只允许创建唯一的对象,并提供它的访问方法.


//单例模式:饿汉式


#include <iostream>
using namespace std;
class Singleton{
public:
    //3)使用静态成员函数获取单例对象
    static Singleton& getInstance(void){
        return s_instance;
    }
    void print(void)const{
        cout << m_data << endl;
    }
private:
    //1)私有化构造函数
    Singleton(int data=0):m_data(data){
        cout << "单例对象被创建了" << endl;  
    }
    //将拷贝构造也声明为私有
    Singleton(const Singleton& that);
private:
    int m_data;
    //2)使用静态成员变量表示单例对象
    static Singleton s_instance;
};
Singleton Singleton::s_instance = 1234;
int main(void)
{
    cout << "main函数开始执行" << endl;
    //Singleton s(123);//error
    //Singleton* ps = new Singleton(123);
    Singleton& s1=Singleton::getInstance();
    Singleton& s2=Singleton::getInstance();
    Singleton& s3=Singleton::getInstance();
   
    cout << "&s1=" << &s1 << endl;
    cout << "&s2=" << &s2 << endl;
    cout << "&s3=" << &s3 << endl;
    s1.print();//1234
    s2.print();//1234
    s3.print();//1234
    return 0;
}
//单例模式:懒汉式
#include <iostream>
using namespace std;
class Singleton{
public:
    //3)使用静态成员函数获取单例对象
    static Singleton& getInstance(void){
        if(s_instance == NULL){
            s_instance = new Singleton(1234);
        }
        ++s_count;
        return *s_instance;
    }
    //单例对象不用即销毁,具体时机?
    //最后一个使用者调用release再销毁!
    void release(void){
        if(--s_count == 0){
            delete s_instance;
            s_instance = NULL;
        }
    }
    void print(void)const{
        cout << m_data << endl;
    }
private:
    //1)私有化构造函数
    Singleton(int data=0):m_data(data){
        cout << "单例对象被创建了" << endl;  
    }
    //将拷贝构造也声明为私有
    Singleton(const Singleton& that);
    ~Singleton(void){
        cout << "单例对象被销毁了" << endl;
    }
private:
    int m_data;
    //2)使用静态成员变量表示单例对象
    static Singleton* s_instance;
    //计数:记录单例对象使用者的个数
    static int s_count;
};
Singleton* Singleton::s_instance = NULL;
int Singleton::s_count = 0;
int main(void)
{
    cout << "main函数开始执行" << endl;
    //Singleton s(123);//error
    //Singleton* ps = new Singleton(123);
    //++s_count ==> 1
    Singleton& s1=Singleton::getInstance();
    //++s_count ==> 2
    Singleton& s2=Singleton::getInstance();
    //++s_count ==> 3
    Singleton& s3=Singleton::getInstance();
   
    cout << "&s1=" << &s1 << endl;
    cout << "&s2=" << &s2 << endl;
    cout << "&s3=" << &s3 << endl;
    s1.print();//1234
    s1.release();//--s_count:2
   
    s2.print();//1234
    s3.print();//1234
    s2.release();//--s_count:1
    s3.release();//--s_count:0,delete
    return 0;
}
目录
相关文章
|
18天前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
29天前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
43 6
|
29天前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
21 0
C++ 多线程之线程管理函数
|
1月前
|
编译器 C语言 C++
C++入门3——类与对象2-2(类的6个默认成员函数)
C++入门3——类与对象2-2(类的6个默认成员函数)
23 3
|
1月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
126 1
|
1月前
|
存储 编译器 C++
C++入门3——类与对象2-1(类的6个默认成员函数)
C++入门3——类与对象2-1(类的6个默认成员函数)
25 1
|
1月前
|
编译器 C语言 C++
C++入门6——模板(泛型编程、函数模板、类模板)
C++入门6——模板(泛型编程、函数模板、类模板)
37 0
C++入门6——模板(泛型编程、函数模板、类模板)
|
1月前
|
C语言 C++
实现两个变量值的互换[C语言和C++的区别]
实现两个变量值的互换[C语言和C++的区别]
17 0
|
22天前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
21 4
|
22天前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
19 4