C++ 类的静态成员函数和静态成员数据

类和static的纠缠无非就是两种。成员函数被static修饰,称为静态成员函数;另一种是成员数据被static修饰,称为静态成员数据。
通过需求出发,引入概念。理解用在什么地方,至于怎么用可以通过翻看代码来回忆。

静态成员变量

静态成员变量是用来干嘛?
需求:创建对象的时候我们想去统计创建了多少份,此时如果我们通过普通的数据成员是没去办法统计的。因为创建完对象以后这些数据都被该对象复制了一份,每个都是独立的。所以我们需要一个很特殊的数据他不属于某一个对象,但是每个对象却可以访问修改它。这个数据就是static静态成员变量。

1、使用静态数据实现

Man.h

#ifndef _MAN_H_
#define _MAN_H_

class Man {
public:
    Man();  // 默认构造函数
    ~Man();  // 析构函数

    int getCount();
    
private:
    static int manCount;  // 静态成员用来统计创建的对象
    // static int manCount = 0;  static静态变量不能在这里初始化
    // static const int manCount = 0;  const修饰的静态成员可以在这里初始化,但是C++11标准才支持
};

#endif

Man.cpp

#include "../include/Man.h"

    int Man::manCount = 0;  // 静态成员数据在实现中初始化,而且不能带static

    // 默认构造函数
    Man::Man() {
        manCount++;  // 静态数据成员可以被对象方法访问到
    } 

    // 析构函数
    Man::~Man() {

    }

    // 返回manCount
    int Man::getCount() {
        return manCount;
    }

main.cpp

#include <iostream>
#include "../include/Man.h"

using namespace std;


int main() {
	Man man1; 
	Man man2;

	cout << man2.getCount() << endl;

	return 0;
}

输入、输出:

➜  code ./a
2
➜  code 

总结:
1、静态成员数据声明的时候不允许初始化,初始化需要在实现文件中去。
2、静态成员数据如果被const修饰,那么可以在声明中去初始化,但是需要C++11标准支持。被修饰后无法再更改。
3、所有对象成员函数都可以访问静态成员变量,但是却不属于某个对象而是属于整个类。

静态成员数据和对象的关系
2、使用全局变量去实现

代码:
// man.h

#ifndef _MAN_H_
#define _MAN_H_

extern int Num;  // 外部声明

class Man {
public:
    Man();  // 默认构造函数
    ~Man();  // 析构函数

    int getCount();

private:
    static int manCount;  // 静态成员用来统计创建的对象
    // static int manCount = 0;  static静态变量不能在这里初始化
};

#endif

// Man.cpp

#include "../include/Man.h"

    int Num = 0;  // 全局变量初始化
    int Man::manCount = 0;  // 静态成员数据在实现中初始化,而且不能带static

    // 默认构造函数
    Man::Man() {
        manCount++;  // 静态数据成员可以被对象方法访问到
        Num++;  //  全局变量实现
    } 

    // 析构函数
    Man::~Man() {

    }

    // 返回manCount
    int Man::getCount() {
        return manCount;
    }

// main.cpp

#include <iostream>
#include "../include/Man.h"

using namespace std;


int main() {
	Man man1;
	Man man2;

	cout << man2.getCount() << endl;
	cout << Num << endl;

	return 0;
}

输入、输出;

➜  code ./a
2
2
➜  code 

静态成员函数

上面的静态成员数据的访问,都是通过对象函数去访问的。那么我们一定要创建个对象,然后在去访问到这个静态数据吗?这样就背离初衷了。C++中提供了静态成员方法,可以通过它去访问静态成员数据。它也和静态成员数据一样是属于类的,每个对象都可以访问到它,但是它不是属于某个对象的。

// Man.h

#ifndef _MAN_H_
#define _MAN_H_

extern int Num;  // 外部声明

class Man {
public:
    Man();  // 默认构造函数
    ~Man();  // 析构函数

    int getCount();

    static int GetCount();  // 静态成员函数

private:
		int c = 0;
    static int manCount;  // 静态成员用来统计创建的对象
    // static int manCount = 0;  static静态变量不能在这里初始化
};

#endif

// Man.cpp

#include "../include/Man.h"

    int Num = 0;  // 全局变量初始化
    int Man::manCount = 0;  // 静态成员数据在实现中初始化,而且不能带static

    // 默认构造函数
    Man::Man() {
        manCount++;  // 静态数据成员可以被对象方法访问到
        Num++;  //  全局变量实现
    } 

    // 析构函数
    Man::~Man() {

    }

    // 返回manCount
    int Man::getCount() {
        return manCount;
    }

    // 静态成员函数和静态成员数据一样实现的时候不能加static
    int Man::GetCount() {
    	 // c = 12; 静态成员函数不能访问对象成员数据
    	 // getCount();  静态成员函数不能访问对象成员方法
        return manCount;
    }

//main.cpp

#include <iostream>
#include "../include/Man.h"

using namespace std;


int main() {
	Man man1;
	Man man2;

	// 通过对象方法访问静态成员数据
	cout << man2.getCount() << endl;

	//访问全局变量
	cout << Num << endl;
	
	// 通过类名来访问静态成员函数
	cout << Man::GetCount() << endl;
	// 通过对象来访问静态方法
	cout << man2.GetCount() << endl;
	
	return 0;
}

输入、输出:

➜  code ./a 
2
2
2
2
➜  code 

总结:
1、静态成员函数可以通过类名、对象来访问
2、静态成员函数不可以访问对象的数据成员和成员函数
3、需要特别注意的时候静态成员方法不可以使用this指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

划水猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值