天天看點

第十三講 靜态成員變量/函數+靜态全局/局部變量—————面向對象進階開發

1 靜态成員變量/函數+靜态全局/局部變量

靜态的作用:

  • 1,延長生命周期(局部變量)
  • 2,都預設初始化為0(全局或局部修飾的變量)
  • 3,隐藏功能(隻對同一個源檔案有效【同名的.h、.cpp】,避免命名沖突)

1.1 靜态成員變量/函數

  • 1,靜态成員變量:同一個類中隻有一份,多個類共用一個;
  • 2,靜态成員函數:函數内沒有this指針,隻能改變靜态變量的值(因為靜态成員函數屬于整個類,在類執行個體化對象之前就已經配置設定空間了,而類的非靜态成員必須在類執行個體化對象後才有記憶體空間),用于配合靜态變量使用;靜态成員函數中不能調用非靜态函數,反之則可以。
#include 
#include 

class A{
public:
    A(){}
    static void func(){
        m_data = 2;
        //m_data2 = 3;//error: invalid use of member 'a' in static member function
    }
    void print(){
        std::cout<<m_data<<std::endl;
    }
private:
    static int m_data;
    int m_data2;
};

int A::m_data = 1;//通過類名調用

int main(){
    A a;
    a.print();
    ((A*)0)->func();//靜态函數
    a.print();
    a.func();//通過對象名調用
    a.print();
    return 0;
}      

1. 2 非成員靜态全局/局部變量

  • 1,靜态全局變量:靜态全局變量在頭檔案中可以聲明也可以定義,隻對同一個源檔案(同名的.h、.cpp)有效,避免命名沖突;但是extern變量在頭檔案中隻能聲明,然後在源檔案(.cpp)中必須有定義(因為extern用于變量,表示它在其他地方定義,在運作前就已經存在)。
  • 2,靜态局部變量:将函數中此變量的值儲存至下一次調用時,隻能被初始化一次(用于避免使用全局變量時,破壞了此變量的通路範圍)

test.h

#ifndef ALGORITHM_TEST_H
#define ALGORITHM_TEST_H

static double g_grade;//不初始化時,預設為0
extern double g_grade2;
//double g_grade3;//錯誤:ld: 1 duplicate symbol for architecture x86_64

void func2();
#endif //ALGORITHM_TEST_H      

test.cpp

#include "test.h"

#include 

double g_grade2 = 100;

void func2(){
    //全局靜态變量
    //列印預設值
    std::cout<<"test.cpp--->g_grade全局靜态變量指派前:"<<g_grade<<std::endl;//g_grade:0
    //列印影印後的值
    g_grade = 92;
    std::cout<<"test.cpp--->g_grade全局靜态變量指派後:"<<g_grade<<std::endl;//g_grade:92
    std::cout<<"test.cpp--->g_grade2全局變量:"<<g_grade2<<std::endl;//g_grade2:96.8
    //  std::cout<<"g_grade3:"<
}      

main.cpp

#include 
#include 
#include "test.h"

int func1(){//靜态局部變量
    static int n = 0;
    n++;
    return n;
}

int main(){
    //局部靜态變量
    std::cout<<"局部靜态變量:";
    for(int i = 0;i < 5;++i){
        std::cout<<func1()<<" ";
        if(i == 4) std::cout<<std::endl;
    }


    //全局變量+全局靜态變量
    std::cout<<"全局變量:"<<std::endl;
    func2();
    std::cout<<"main.cpp--->g_grade全局靜态變量指派前:"<<g_grade<<std::endl;//g_grade:0
    std::cout<<"main.cpp--->g_grade2全局變量指派前:"<<g_grade2<<std::endl;//g_grade2:100
    g_grade = 96.8;
    g_grade2 = 96.8;
    // g_grade3 = 98.7;
    std::cout<<"main.cpp--->g_grade全局靜态變量指派後:"<<g_grade<<std::endl;//g_grade:96.8
    std::cout<<"main.cpp--->g_grade2全局變量指派後:"<<g_grade2<<std::endl;//g_grade2:96.8
    //std::cout<<"g_grade3:"<

    return 0;
}      

輸出:

局部靜态變量:1 2 3 4 5 
全局變量:
test.cpp--->g_grade全局靜态變量指派前:0
test.cpp--->g_grade全局靜态變量指派後:92
test.cpp--->g_grade2全局變量:100
main.cpp--->g_grade全局靜态變量指派前:0
main.cpp--->g_grade2全局變量指派前:100
main.cpp--->g_grade全局靜态變量指派後:96.8
main.cpp--->g_grade2全局變量指派後:96.8      

1.3 靜态非成員函數

  • 1,作用:聲明的函數定義時,隻在目前檔案附屬的.cpp中有效,在其他地方可以重複定義。

    test.h

#ifndef ALGORITHM_TEST_H
#define ALGORITHM_TEST_H

void func2();
static  void func3();

#endif //ALGORITHM_TEST_H      
#include "test.h"
#include 

void func2(){

}

void func3() {
    std::cout<<"test.cpp--->全局靜态函數:func3()";
}      
#include 
#include 
#include "test.h"

//void func2(){//錯誤:ld: 1 duplicate symbol for architecture x86_64
//
//}

//可以在這裡重複定義func3
void func3(){
    std::cout<<"main.cpp--->全局靜态函數:func3()";
}

int main(){
    func3();//要調用此函數,main.cpp中必須定義func3,其他源檔案中定義無效

    return 0;
}