前言
在类定义中,它的成员(包括成员变量和成员函数),这些成员可以用关键字static声明为静态的,称为静态成员。
不管这个类创建了多少个对象,静态成员只有一个拷贝,这个拷贝被所有属于这个类的对象共享。(本文参考奇牛编程)
1 类的静态成员
在一个类中,若将一个成员变量声明为static,这种成员称为静态成员变量。与一般的数据成员不同,无论建立了多少个对象,都只有一个静态数据的拷贝。静态成员变量,属于某个类,所有对象共享。
该过程如下图所示:(即h1和h2共享一块地址)
静态变量,是在编译阶段就分配空间,对象还没有创建时,就已经分配空间。
注意:对于非 const 的类静态成员,只能在类的实现文件中初始化。
const 类静态成员,可以在类内设置初始值,也可以在类的实现文件中设置初始值。(但是不要同时在这两个地方初始化,只能初始化 1 次)
参考代码如下:
#include<iostream>
using namespace std;
class Human
{
public:
Human();
int getCount();
private:
static int count;
};
int Human::count = 0;
int Human::getCount() {
return count;
}
Human::Human() {
count++;
}
int main() {
Human h1,h2;
cout << h1.getCount() << endl;
cout << h2.getCount() << endl;
}
2 类的静态成员函数
在类定义中,前面有static说明的成员函数称为静态成员函数。静态成员函数使用方式和静态变量一样,同样在对象没有创建前,即可通过类名调用。静态成员函数主要为了访问静态变量,但是,不能访问普通成员变量。
静态成员函数的意义,不在于信息共享,数据沟通,而在于管理静态数据成员,完成对静态数据成员的封装。
注意:1. 可以直接通过类来访问【更常用】,也可以通过对象(实例)来访问。
2. 在类的静态方法中,不能访问普通数据成员和普通成员函数(对象的数据成员和成员函数)
参考代码如下:
#include <iostream>
using namespace std;
class Human {
public:
Human() {
count++;
}
/*int getCount(){
return count;
}*/ //普通成员函数也可以直接访问静态成员变量
static int getCount() {
// cout << age; 静态成员函数不能访问普通成员
// cout << getAge();静态成员函数也不能访问普通成员函数
return count;
}
private:
static int count;//静态数据成员
};
int Human::count = 0;
void test() {
//普通成员函数方法:通过对象来调用
//Human tmp;
//cout << tmp.getCount() << endl;
//静态成员函数用法:类名::静态方法
cout << Human::getCount() << endl; //227
}
int main() {
Human m1, m2;
cout << m1.getCount() << endl;
test();
return 0;
}
3 静态成员变量和静态成员函数小结
由上述代码可以总结出如下结论:
1)对象的成员函数(没有 static 的成员函数)内部,可以直接访问“静态数据成员”;
类的静态成员函数(有 static 的成员函数)内部,可以直接访问“静态数据成员”
即:所有的成员函数,都可以访问静态数据成员。
2)对象可以直接访问静态成员函数(m1.getCount())
类可以直接访问静态成员函数(Human::getCount())
在类的静态成员函数(类的静态方法)内部,只能访问静态数据成员
4 const数据成员
常对象只能调用const的成员函数
常对象可访问 const 或非 const 数据成员,不能修改,除非成员用mutable修饰
const 数据成员的初始化方式:
1. 使用类内值(C++11 支持 )
2. 使用构造函数的初始化列表
(如果同时使用这两种方式,以初始化列表中的值为最终初始化结果)
注意: 不能在构造函数或其他成员函数内,对 const 成员赋值!
参考代码如下:
#include <iostream>
#include <string.h>
using namespace std;
class Human {
public:
Human();
static int getCount();
//const string bloodType = "A"; //C++11:类内初始值 (如果该行不注释掉则打印B型血)
const string bloodType;
void description();
private:
static int count;
};
//string Human::bloodType = "B";
int Human::count = 0;
Human::Human() :bloodType("B") {
count++;
}
int Human::getCount() {
return count;
}
void Human::description() {
cout << "bloodType:" << bloodType << endl;
}
int main() {
Human h1;
h1.description();
}
5 const成员函数
C++认为,const(常量)对象,如果允许去调用普通的成员函数,而这个成员函数内部可能会修改这个对象的数据成员!而这讲导致 const 对象不再是 const 对象!
const 成员函数内,不能修改任何数据成员!
C++的成员函数设置建议:
如果一个对象的成员函数,不会修改任何数据成员,那么就强烈:把这个成员函数,定义为 const
参考代码如下:
#include <iostream>
#include <string.h>
using namespace std;
class Human{
public:
Human();
void description() const;
const string bloodType;
int getCount();
private:
static int count;
};
int Human::count = 0;
Human::Human():bloodType("B型") {
}
void Human::description ()const
{
cout << "bloodType:" << bloodType << endl;
}
int Human::getCount() {
return count;
}
int main() {
const Human m1;
//m1.getCount();//不能调用普通成员函数
m1.bloodType;//可以访问数据成员
m1.description();
}