首页 > 代码库 > 类的静态成员

类的静态成员

类的静态成员不同于普通成员,它们有自己的特点,我将以下面的类为例讲解。


//设计银行账户类Account
#include <iostream>
#include <string>
class Account
{
private:
	std::string owner;//账户名
	double amount;//余额
	static double interestRate;//利率,static数据成员声明,此定义在类外部
	//整型const static数据成员在类定义中声明时需初始化
        static const int period=30;
	double daily_tbl[period];
public:
	//构造函数
	Account(const std::string own="noname",double amou=0):
	  owner(own),amount(amou){}//注意,构造函数不能初始化static数据成员
	  //声明存款日期,它是public static数据成员
	static std::size_t withdrawdate;
	//计算余额
       double Applyint()
	{
		amount+=amount*interestRate;
	}
	//返回当前利率
        static double rate()//类内部定义的static成员函数
	{
		return interestRate;
	}
	//设置新利率
	static void setrate(double );//类内部声明static成员函数,在类外部定义
};
	double Account::interestRate=2.5;//在类外部定义static数据成员并初始化,必须使用类作用符,不再标志为static
	std::size_t Account::withdrawdate=20141222;//定义存款日期且初始化
	const int period;//整型const static在类定义体外部定义式不必再指定初始值
	//类外部定义setrate
	void Account::setrate(double newrate)
	{
		interestRate=newrate;
	}
int main()
{
	Account act1;//类Account实例化对象act1
	Account *act1ptr=&act1;//类指针act1ptr指向act1对象
	Account &act2=act1;//act2是act1的引用

	//四种方式调用pubilc static数据成员withdrawdate
	size_t date;
	date=act1.withdrawdate;//通过对象间接调用
	date=act1ptr->withdrawdate;//通过指针间接调用
	date=act2.withdrawdate;//通过act1的引用act2间接调用
	date=Account::withdrawdate;//通过类Account直接调用

	//只能通过成员函数间接调用private static 数据成员
	double rate;//定义一个变量rate,用于接受rate()函数返回的利率
    rate=Account::rate();//这里用类作用域操作符直接调用static成员函数
	//rate=Account::interestRate;//错误,不能直接访问private static数据成员

	//四种方式调用pubilc static成员函数rate()
	double rate;//定义rate,用于接受返回的利率
	date=act1.rate();//通过对象间接调用
	date=act1ptr->rate();//通过指针间接调用
	date=act2.rate();//通过act1的引用act2间接调用
	date=Account::rate();//通过类Account直接调用
}


静态数据成员

通常,非static数据成员存在于类类型的每个对象中,而static数据成员却独立于该类的任意对象而存在:每个static数据成员是与类关联的对象,并不与该类的对象相关联。
  1. 定义——static关键字

    static数据成员必须在类定义体外部定义(只能定义一次),且应该在定义时进行初始化,因为static数据成员不是通过类的构造函数进行初始化的。
    如上述程序中的利率interestRate,它在类定义体外部定义如下:

    double Account::interestRate=2.5;//在类外部定义static数据成员并初始化,必须使用类作用域操作符(::),不再标志为static

  2. 特殊的整型const static数据成员

     整型const static数据成员必须在类的定义体中初始化,且仍需在类的定义体之外进行定义,此时不必再指定初始值。
    如上述程序中的period:

    class Account

    {

    //整型conststatic数据成员在类定义中声明时需初始化

    staticconst int period=30;

    };

    const int period;//整型const static在类定义体外部定义式不必再指定初始值

  3. 调用static数据成员
    1) public static数据成员
            可以通过作用域操作符(::)直接调用public static成员,或者通过对象、引用或指向该类类型对象的指针间接调用public static成员。
            如上述程序中:

    Account act1;//类Account实例化对象act1
    Account*act1ptr=&act1;//类指针act1ptr指向act1对象
    Account&act2=act1;//act2是act1的引用
    //四种方式调用pubilc static数据成员rate()
        size_t date;
        date=act1.rate();//通过对象间接调用
        date=act1ptr->rate();//通过指针间接调用
        date=act2.rate();//通过act1的引用act2间接调用
        date=Account::rate();//通过类Account直接调用

    我们要知道,虽然可以通过对象间接调用static数据成员,但是它是属于类的,不属于对象。
    2)private static数据成员
           只能通过成员函数间接调用private static 数据成员,静态成员函数和普通成员函数都可以访问private static。
           如上述程序中的返回利率函数rate():

    double rate;//定义一个变量rate用于接受rate()函数返回的利率
    rate=rate();
    rate=Account::rate();//这里用类作用域操作符直接调用static成员函数rate(),rate()间接返回利率interestRate
    //rate=Account::interestRate;//错误,不能直接访问private static数据成员
  4. static数据成员的特殊性
    1) static数据成员的类型可以是该成员所属类的类类型,而非static成员被限定声明为其自身类对象的指针或引用

    class Account
    {
      …
    private:
    static Account act4;//正确,stactic数据成员的类型可以是自身类的类型
    Account amount;//错误,普通数据成员amount不能是自身类的类型
    Account *act2ptr;//正确
    ...
    };
    2) static数据成员可用作默认实参,非static数据成员则不可以

    //窗口类Screen
    class Screen
    {
    public:
    //清除屏幕上的特定字符
    Screen& clear(char=bkground);
    private:
    static const charbkground=’#’;
    };


静态成员函数

  1. 定义—— 只需加上static关键字

    static成员函数可以在类内部定义,也可以在类外部定义。在类内部定义时,加上static;在类外部定义时,类内部的声明需加上static,在类外部的定义式不需再加static,但必须使用类作用域操作符(::)。
    如上述程序中的内部定义的rate():
    static double rate()

           {

           return interestRate;

           }
    外部定义的设置新利率函数setrate():

    class Account

    {

    public:

    //设置新利率

           static void setrate(double );//类内部声明static成员函数,在类外部定义…

    };

    //类外部定义设置新利率函数setrate

    void Account::setrate(double newrate)

    {

           interestRate=newrate;

    }

  2. static成员函数的特殊性
    1) static成员函数不能声明为const

           如:static void setrate(double ) const;//错误

    2)   static成员函数不能声明为虚函数

    3) static成员函数没有this指针
           这将导致static成员函数不能访问非static数据成员,只能访问static数据成员,而普通成员函数则无此限制。

           以上述程序中的返回当前利率为例:

    class Account
    {
               private:
               static double interestRate;
    public:
    //返回当前利率
    staticdouble rate()//static成员函数访问static 数据成员
           {
                  return interestRate;
           };
    }

  3. 调用static成员函数
    1) public static成员函数
           与调用public static数据成员类似,也有四种方式:可以通过作用域操作符(::)直接调用public static成员,或者通过对象、引用或指向该类类型对象的指针间接调用public static成员。
          仍以返回当前利率函数rate()为例:

    Account act1;//类Account实例化对象act1
    Account*act1ptr=&act1;//类指针act1ptr指向act1对象
    Account&act2=act1;//act2是act1的引用
    //四种方式调用pubilc static成员函数rate()
    double rate;//定义rate,用于接受返回的利率
    rate=act1.rate();//通过对象间接调用
    rate=act1ptr->rate();//通过指针间接调用
    rate=act2.rate();//通过act1的引用act2间接调用
    rate=Account::rate();//通过类Account直接调用

    2) private static成员函数

           这类函数一般很少用到,这里就不再讨论。

    以上内容均是自己在看《C++ Primer》的一些总结,或摘除,或自己添加,欢迎大家指正。

类的静态成员