本文学习自 狄泰软件学院 唐佐林老师的 C++课程
通过新需求 《统计程序运行期间某个类的对象数目》 来引出了 静态成员变量。
实验1 :类中的成员变量的是每个对象私有的,对象间的成员变量不共享。
实验2:静态成员变量使用
通过对象名直接访问 公有静态成员变量
通过类名直接访问 公有静态成员变量
在非const 成员函数中,可以直接访问修改所有的成员变量,也可以通过对象名访问所有的成员变量
实验1 :类中的成员变量的是每个对象私有的,对象间的成员变量不共享。
#include <stdio.h>
class Test
{
private:
int mCount;
public:
Test() : mCount(0)
{
mCount++;
}
~Test()
{
--mCount;
}
int getCount()
{
return mCount;
}
};
Test gTest;
int main()
{
Test t1;
Test t2;
printf("count = %d\n", gTest.getCount());
printf("count = %d\n", t1.getCount());
printf("count = %d\n", t2.getCount());
return 0;
}
mhr@ubuntu:~/work/c++$ g++ 25-1.cpp
mhr@ubuntu:~/work/c++$ ./a.out
count = 1
count = 1
count = 1
mhr@ubuntu:~/work/c++$
这是因为成员变量是每个对象私有的,不共享!!本例中的mCount 为每个对象私有成员。
使用全局变量倒是可以实现功能,但是不安全!! 成员函数可以访问全局变量,全局变量在哪里都可以访问。
由于静态成员变量不隶属于任何对象,是隶属于整个类,所以静态成员变量不会占用对象的空间,所以静态成员变量只能在类的外部单独分配空间,静态成员变量的存储空间位于全局数据区。也就是说,在本质上,静态成员变量 和 全局变量 以及 静态局部变量是一致的 存储在一个地方。
实验2:静态成员变量使用
#include <stdio.h>
class Test
{
private:
static int cCount;
public:
Test()
{
cCount++;
}
~Test()
{
--cCount;
}
int getCount()
{
return cCount;
}
};
/*
类的静态成员变量不隶属于任何对象,需要在类的外部分配存储空间
如果没有在外部分配静态成员变量的的空间,类对象就会因为找不到静态成员变量的空间而无法访问静态成员变量
*/
int Test::cCount = 0;
Test gTest;
int main()
{
Test t1;
Test t2;
printf("count = %d\n", gTest.getCount());
printf("count = %d\n", t1.getCount());
printf("count = %d\n", t2.getCount());
Test* pt = new Test();
printf("count = %d\n", pt->getCount());
delete pt;
printf("count = %d\n", gTest.getCount());
return 0;
}
mhr@ubuntu:~/work/c++$
mhr@ubuntu:~/work/c++$ g++ 25-2.cpp
mhr@ubuntu:~/work/c++$ ./a.out
count = 3
count = 3
count = 3
count = 4
count = 3
mhr@ubuntu:~/work/c++$
实验总结:
错误重现:
普通的成员变量,创建对象的时候会自动根据声明,创建对应的成员变量,如果要初始化的话 需要使用初始化列表。但是对于静态成员变量,他的存储空间是在类的外部的,不隶属于任何的对象,隶属于整个类,静态成员变量不会占用对象的空间,所以静态成员变量只能在类的外部单独分配空间。但是如果只在类中声明了静态成员变量,而没有在类外为静态成员变量申请空间,那么对象就无法访问到改静态成员变量了。
#include <stdio.h>
class Test
{
private:
static int cCount;
public:
Test()
{
cCount++;
}
~Test()
{
--cCount;
}
int getCount()
{
return cCount;
}
};
//int Test::cCount = 0;//不在外部为静态成员变量申请空间
Test gTest;
int main()
{
Test t1;
Test t2;
printf("count = %d\n", gTest.getCount());
printf("count = %d\n", t1.getCount());
printf("count = %d\n", t2.getCount());
return 0;
}
mhr@ubuntu:~/work/c++$
mhr@ubuntu:~/work/c++$ g++ 25-2.cpp
/tmp/ccQKPih1.o: In function `Test::Test()':
25-2.cpp:(.text._ZN4TestC2Ev[_ZN4TestC5Ev]+0xa): undefined reference to `Test::cCount'
25-2.cpp:(.text._ZN4TestC2Ev[_ZN4TestC5Ev]+0x13): undefined reference to `Test::cCount'
/tmp/ccQKPih1.o: In function `Test::~Test()':
25-2.cpp:(.text._ZN4TestD2Ev[_ZN4TestD5Ev]+0xa): undefined reference to `Test::cCount'
25-2.cpp:(.text._ZN4TestD2Ev[_ZN4TestD5Ev]+0x13): undefined reference to `Test::cCount'
/tmp/ccQKPih1.o: In function `Test::getCount()':
25-2.cpp:(.text._ZN4Test8getCountEv[_ZN4Test8getCountEv]+0xa): undefined reference to `Test::cCount'
collect2: error: ld returned 1 exit status
mhr@ubuntu:~/work/c++$