Aoki Job Seeker

静态成员

2019-03-21
C++

静态成员



写在前面

在类定义中,它的成员(包括成员变量和成员函数),这些成员可以用关键字static声明为静态的,称为静态成员。
不管这个类创建了多少个对象,静态成员只有一个拷贝,这个拷贝被所有属于这个类的对象共享。

1.静态成员变量

在一个类中,若将一个成员变量声明为static,这种成员变量称为静态成员变量。与一般的数据成员不同,无论建立多少个对象,都只有一个静态数据的拷贝。静态成员变量,属于某个类,所有对象共享。
静态变量,是在编译阶段就分配空间,对象还没创建,就已经分配空间。

  • 静态成员变量必须在类中声明,在类外定义
  • 静态数据成员不属于某个对象,在为对象分配空间中不包括静态成员所占的空间
  • 静态数据成员可以通过类名或者对象名来引用
#include <iostream>
using namespace std;

class Person
{
public:
	static int m_Age;
private:
	static int m_other;
};

int Person::m_Age = 100;
int Person::m_other = 20;

void test()
{
	Person p1;
	p1.m_Age = 10;
	cout << "p1=" << p1.m_Age << endl;
	cout << "p1的地址为:" << &p1.m_Age << endl;
	Person p2;
	p2.m_Age = 20;
	cout << "p1=" << p1.m_Age << endl;
	cout << "p2=" << p2.m_Age << endl;

	cout << "p2的地址为:" << &p2.m_Age << endl;

}
int main()
{
	test();

}

输出结果如下图:

通过输出结果我们可以很清除地看到,静态成员变量是所有对象共享的。任何一个对象都可以改变静态变量的值,但是静态变量不属于任何一个对象。
下面我们看一下对象的大小,以此来说明静态数据成员不属于某个对象,在为对象分配的空间中不包括静态成员所占的空间。

#include <iostream>
using namespace std;

class Person
{
public:
	static int m_Age;
private:
	static int m_other;
};

int Person::m_Age = 100;
int Person::m_other = 20;

void test()
{
	Person p;
	cout << sizeof(p) << endl;
	cout << sizeof(p.m_Age) << endl;

}
int main()
{
	test();
}

输出结果如下图:
我们可以看出,对象的大小为1,而静态成员佰利联的大小为4。
当我们尝试去访问m_other时,编译器会报错,因为它是一个私有数据成员,这也说明了静态成员变量是有权限控制机制的。

2.静态成员变量

在类定义中,前面有static说明的成员函数称为静态成员函数。静态成员函数使用方式和静态变量一样,同样在对象没有创建前创建,即可他通过类名调用。静态成员函数主要为了访问静态变量,但是不能访问普通成员变量。
静态成员函数的意义,不在于信息共享,数据沟通,而在于管理静态数据成员,完成对静态数据成员的封装。

  • 静态成员函数只能访问静态变量,不能访问普通成员变量
  • 静态成员函数的使用和静态成员变量一样
  • 静态成员函数也有访问权限
  • 普通成员函数可以访问静态成员变量,也可以访问非静态变量


如上图所示,当我们使用静态成员函数试图访问非静态成员变量时,编译器会报错,提示信息如上图所示。

在上图中,我试图使用类名来访问私有的静态成员函数,编译器报错,因为静态成员函数也有自己的权限。


#include <iostream>
using namespace std;

class Person
{
public:
	static void func()//静态成员函数
	{
		m_Age = 100;
		//m_A = 20;//作用域
		cout << "静态成员函数调用" << endl;
	}
	static int m_Age;
	int m_A;
private:
	static int m_other;
	static void func01()
	{
		cout << "静态成员函数func2调用" << endl;
	}
};

int Person::m_Age = 100;
int Person::m_other = 20;

void test()
{
	Person p1;
	Person p2;
	p1.func();
	p2.func();
	Person::func();
	//Person::func01();//作用域
}
int main()
{
	test();
}

输出结果如下图:

3.总结

  1. 静态成员变量
    • 编译阶段分配内存
    • 所有对象共享数据
    • 通过对象访问,通过类名访问
    • 有权限控制
    • 类内声明,类外初始化
  2. 静态成员函数
    • 可以访问静态成员变量,不可以访问普通成员变量
    • 普通成员函数都可以访问
    • 静态成员函数也有权限
    • 可以通过对象访问,也可以通过类名访问






The End



Similar Posts

上一篇 拷贝构造函数

Comments