C++ 静态数据成员 静态成员函数

类中的静态成员数据可以在类体中初始化的只有常量整型的成员,因为静态数据成员可以为类中的其它数据成员或函数成员所用,所以考虑到一个数组如果用静态成员作为维数的话,则应该让该成员被常量表达式初始化,所以C++允许常量整型的静态成员在类体中被初始化,而其它类型一律不允许.注意这里的整型不单止int,只要是可以用来表示数组维数的类型都是整型.同时,在类中被声明的静态成员一般要在类外中被定义(即初始化).即使是在类中初始化了的常量整型数据成员也要在类外定义一次(只不过它不用再初始化而已),这其中也包括了类数据成员.在vs2005中提供了优化,可以在类中声明了而不在类外定义.但原则上是要做这一步的.

静态数据成员可以声明自身类类型的成员,而非静态的不行,只能声明指针或引用.同样,该自身类型的成员要在类外被定义一次,而这种情况编译器不再做优化,所以如果不提供定义,会在链接时刻出错.如果是非自身类类型的数据成员,编译器同样会优化,调用缺省构造函数初始化.

所以,请记住一下三点:

1.标准定义里静态成员都要在类外被定义一次.只有常量整型的静态成员可以在类体中用一常量值初始化.
2.任何其它类型的数据成员在类体内不管用什么方法初始化都是不允许的.
3.在类中被声明的静态成员一般要在类外中被定义(即初始化)

数据成员中如果要用到另一个数据成员的话,该被用到的数据成员要被声明在前,这跟先声明再使用的原则是一致的.而成员函数则不用限制,成员函数使用类中的数据成员时会查找类中的所有数据成员,并不要求数据成员先声明.静态数据成员还可以做为类成员函数的缺省参数,不管其是否常量表达式.常量表达式只影响作为数组维数的数据成员.

静态数据成员在被用到时并不需要隐式调用this指针,这意味着,它只要不是const类型,则它在任何成员函数里都可以被修改,而且这是合法的.任何函数即包括了const和volatile.最后说下静态成员函数.静态成员函数就是为了方便使用静态成员数据出现的.因为静态成员数据使用时可以独立于对象,所以为了可以更方便地使用静态数据,就有了静态成员函数.静态成员函数中不含this指针,这意味着,它不可以访问非静态的数据成员,如果这样做的话,因为没有this指针,它不知道要调用的是哪一个对象的数据成员.

同样,静态成员函数可以被const和volatile对象调用.但记住,静态成员函数不允许修饰符.因为它没有this指针.

 

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

一 静态数据成员:

类体中的数据成员的声明前加上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;//错误
};


最后要说的一点是,静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值