博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ static成员变量与static成员函数
阅读量:5221 次
发布时间:2019-06-14

本文共 2551 字,大约阅读时间需要 8 分钟。

类中的静态成员真是个让人爱恨交加的特性。我决定好好总结一下静态类成员的知识点,以便自己在以后面试中,在此类问题上不在被动。 

静态类成员包括静态数据成员和静态函数成员两部分。 
一 静态数据成员: 
类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。同时,静态数据成员还具有以下特点: 
1.静态数据成员的定义。 
静态数据成员实际上是类域中的全局变量。所以,静态数据成员的定义(初始化)不应该被放在头文件中。 
其定义方式与全局变量相同。举例如下: 
xxx.h文件 
class base{ 
private: 
static const int _i;//声明,标准c++支持有序类型在类体中初始化,但vc6不支持。 
}; 
xxx.cpp文件 
const int base::_i=10;//定义(初始化)时不受private和protected访问限制. 
注:不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的错误。即使加上#ifndef #define #endif或者#pragma once也不行。 
2.静态数据成员被 类的所有对象所共享,包括该类派生类的对象。即派生类对象与基类对象共享基类的静态数据成员。举例如下: 
class base{ 
public : 
static int _num;//声明 
}; 
int base::_num=0;//静态数据成员的真正定义 
class derived:public base{ 
}; 
main() 
base a; 
derived b; 
a._num++; 
cout<<"base class static data number _num is"<<a._num<<endl; 
b._num++; 
cout<<"derived class static data number _num is"<<b._num<<endl; 
// 结果为1,2;可见派生类与基类共用一个静态数据成员。 
3.静态数据成员可以成为成员函数的可选参数,而普通数据成员则不可以。举例如下: 
class base{ 
public : 
static int _staticVar; 
int _var; 
void foo1(int i=_staticVar);//正确,_staticVar为静态数据成员 
void foo2(int i=_var);//错误,_var为普通数据成员 
}; 
4.★静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为 所属类类型的指针或引用。举例如下: 
class base{ 
public : 
static base _object1;//正确,静态数据成员 
base _object2;//错误 
base *pObject;//正确,指针 
base &mObject;//正确,引用 
}; 
5.★这个特性,我不知道是属于标准c++中的特性,还是vc6自己的特性。 
静态数据成员的值在const成员函数中可以被合法的改变。举例如下: 
class base{ 
public: 
base(){_i=0;_val=0;} 
mutable int _i; 
static int _staticVal; 
int _val; 
void test() const{//const 成员函数 
_i++;//正确,mutable数据成员 
_staticVal++;//正确,static数据成员 
_val++;//错误 
}; 
int base::_staticVal=0; 
二,静态成员函数 
静态成员函数没有什么太多好讲的。 
1.静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用 类成员函数指针来储存。举例如下: 
class base{ 
static int func1(); 
int func2(); 
}; 
int (*pf1)()=&base::func1;//普通的函数指针 
int (base::*pf2)()=&base::func2;//成员函数指针 
2.静态成员函数不可以调用类的非静态成员。因为静态成员函数不含this指针。 
3.静态成员函数不可以同时声明为 virtual、const、volatile函数。举例如下: 
class base{ 
virtual static void func1();//错误 
static void func2() const;//错误 
static void func3() volatile;//错误 
}; 
最后要说的一点是,静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问,举例如下:

#include <iostream>

using namespace std;

class A

{
public:
 int m_a;
 static int m_count; // 注意属性为public
public:
 A(int x):m_a(x){cout<<"A"<<endl;};
 int getData()
 {
  return m_count;
 }
 int get_m_a_data() // 非静态成员函数可以访问静态成员变量
 {
  m_count +=1;
  return m_count;
 }
 static int get_m_count()
 {
  //m_a +=1;    // 静态成员函数没有this指针,不能访问非静态成员变量
  //return m_a; // 同上

  m_count +=1;

  return m_count;
  
 }
};

int A:: m_count=0; // 静态成员变量一定要初始化

int main()

{
 
 cout<<m_count<<endl; // 报错
 cout<<A::m_count<<endl;
 
 return 0;
}

 

转自:

转载于:https://www.cnblogs.com/azbane/p/7266835.html

你可能感兴趣的文章
《代码阅读方法与实现》阅读笔记一
查看>>
解决 sublime text3 运行python文件无法input的问题
查看>>
javascript面相对象编程,封装与继承
查看>>
Atlas命名空间Sys.Data下控件介绍——DataColumn,DataRow和DataTable
查看>>
Java中正则表达式的使用
查看>>
算法之搜索篇
查看>>
新的开始
查看>>
java Facade模式
查看>>
NYOJ 120校园网络(有向图的强连通分量)(Kosaraju算法)
查看>>
SpringAop与AspectJ
查看>>
Leetcode 226: Invert Binary Tree
查看>>
http站点转https站点教程
查看>>
解决miner.start() 返回null
查看>>
关于MFC中窗口的销毁
查看>>
bzoj 2007: [Noi2010]海拔【最小割+dijskstra】
查看>>
BZOJ 1001--[BeiJing2006]狼抓兔子(最短路&对偶图)
查看>>
C# Dynamic通用反序列化Json类型并遍历属性比较
查看>>
128 Longest Consecutive Sequence 一个无序整数数组中找到最长连续序列
查看>>
定制jackson的自定义序列化(null值的处理)
查看>>
auth模块
查看>>