学习笔记之深入浅出MFC 第8章 C++重要特性----静态变量(static)
2016-05-02 19:57
471 查看
静态成员(变量和函数)
静态成员变量或函数有什么用呢?前面我们讲了类及类成员,一般类是指抽象的特性,必须对象化(实例化)之后才能进行操作。那么,假如类的某一个变量都是一样的值,没必要一个对象一个对象的设置呢?我们可不可以直接对类操作一下,从而避免了去设置每一个对象里的此变量呢?当然有,方法就是这一节要讲的静态变量。
举个例子,假如有一个类,专门用来处理存款帐户,它至少应该要有存户的姓名、地址、存款额、利率等成员变量:
class SavingAccount
{
private:
char m_name[40]; //存户姓名
char m_addr[60]; //存户地址
double m_total; //存款额
double m_rate; //利率
};
如果这家银行采用浮动利率,每个账户的利息都是根据当天的挂牌利率来计算。那么这个时候m_rate就不适合成为每个账户对象中的一笔数据,否则每天一开市,光把所有账户内容叫出来,修改m_rate的值,就花掉不少时间。m_rate应该独立在各对象之外,成为类的数据。
这个时候就可以在m_rate前面加上static修饰词:
class SavingAccount
{
private:
char m_name[40]; //存户姓名
char m_addr[60]; //存户地址
double m_total; //存款额
static double m_rate; //利率
};
static成员变量不属于对象的一部分,而是类的一部分。
这个地方需要说明一下:如果是对象的成员,那么不能在类里面直接操作,必须实例化之后才能操作变量。这里加上static的静态变量之后,这个变量就是类的成员,还没有诞生任何对象的时候就可以操作,也就是说类存在就可以直接处理这个变量,所以完全可以当作全局变量来使用,在模块化程序设计中,为
4000
了增加模块的内聚性和独立性,不允许使用全局变量,那么就可以使用类的静态变量来实现全局变量的功能。
1、static静态成员变量的初始化
不要把static成员变量的初始化操作放在类的构造函数中,因为构造函数在每一次对象实例化中都会被调用,那么变量的初值就会被设定多次,这时应该避免的;也不要把初始化操作放在头文件中,因为它可能被载入许多地方,因此也可能被执行许多次。
应该在应用程序文件中,类以外的任何位置设定其初值。例如在main之中或全局函数中,或任何函数之外:
double SavingAccount :: m_rate = 0.0075; //设立static成员变量的初值
请注意,static成员变量的类型也出现在初值设定句中,因为这是一个初值设定操作,而不是一个赋值操作。事实上,static成员变量是在这时候(而不是在类声明中)才定义出来的。如果没有做这个初始化操作,会产生链接错误。
另外,设定static成员变量初值时,不需要考虑m_rate是不是private数据,因为初始化时不受任何存取权限的束缚。
2、static成员变量的存取方式
可以是在没有诞生任何对象实例之前的存取方式:
void main()
{
SavingAccount :: m_rate = 0.0075; //想要这么赋值,必须把m_rate权限改为public。除了初始化操作之外都必须受存取权限的限制
}
也可以在产生一个对象之后:
void main()
{
SavingAccount myAccount;
myAccount.m_rate = 0.0075; //当然这里也要把m_rate权限改为public
}
这里需要区分一下观念:static成员变量除了是类的或对象的一个变量之外,还是脱离对象之外的一个变量。所以既可以跟其他类成员变量一样赋值操作,也可以直接用类来操作,这时候可以想象它是一个全局变量。为了区分static变量,第一种用类赋值的方法比较不容易出错。
3、考虑static成员变量的权限操作
当然,虽然任何函数(包括全局函数或成员函数,static或non-static)都可以存取static成员变量。但是前提是必须考虑成员变量的权限,所以private static成员变量必须设计一个static成员函数:
还是上面的例子:
class SavingAccount
{
private:
char m_name[40]; //存户姓名
char m_addr[60]; //存户地址
double m_total; //存款额
static double m_rate; //利率
public:
static void setRate(double newRate) { m_rate = newRate; }
};
double SavingAccount :: m_rate = 0.0075; //设定static成员变量的初值
void main()
{
SavingAccount :: setRate(0.0074); //直接调用类的static成员函数
或者
SavingAccount myAccount;
myAccount.setRate(0.0074); //通过对象调用staitc成员函数
}
因为static不需要借助任何对象,就可以直接通过类调用执行,所以编译器不会为它暗加一个this指针。也因为如此,static成员函数无法处理类中的non-static成员变量。这是因为前面介绍过,成员函数之所以能够以单一一份函数码处理各个对象的数据而不紊乱,完全是靠的this指针的指示。static成员函数“没有this参数”这种性质。
静态成员变量或函数有什么用呢?前面我们讲了类及类成员,一般类是指抽象的特性,必须对象化(实例化)之后才能进行操作。那么,假如类的某一个变量都是一样的值,没必要一个对象一个对象的设置呢?我们可不可以直接对类操作一下,从而避免了去设置每一个对象里的此变量呢?当然有,方法就是这一节要讲的静态变量。
举个例子,假如有一个类,专门用来处理存款帐户,它至少应该要有存户的姓名、地址、存款额、利率等成员变量:
class SavingAccount
{
private:
char m_name[40]; //存户姓名
char m_addr[60]; //存户地址
double m_total; //存款额
double m_rate; //利率
};
如果这家银行采用浮动利率,每个账户的利息都是根据当天的挂牌利率来计算。那么这个时候m_rate就不适合成为每个账户对象中的一笔数据,否则每天一开市,光把所有账户内容叫出来,修改m_rate的值,就花掉不少时间。m_rate应该独立在各对象之外,成为类的数据。
这个时候就可以在m_rate前面加上static修饰词:
class SavingAccount
{
private:
char m_name[40]; //存户姓名
char m_addr[60]; //存户地址
double m_total; //存款额
static double m_rate; //利率
};
static成员变量不属于对象的一部分,而是类的一部分。
这个地方需要说明一下:如果是对象的成员,那么不能在类里面直接操作,必须实例化之后才能操作变量。这里加上static的静态变量之后,这个变量就是类的成员,还没有诞生任何对象的时候就可以操作,也就是说类存在就可以直接处理这个变量,所以完全可以当作全局变量来使用,在模块化程序设计中,为
4000
了增加模块的内聚性和独立性,不允许使用全局变量,那么就可以使用类的静态变量来实现全局变量的功能。
1、static静态成员变量的初始化
不要把static成员变量的初始化操作放在类的构造函数中,因为构造函数在每一次对象实例化中都会被调用,那么变量的初值就会被设定多次,这时应该避免的;也不要把初始化操作放在头文件中,因为它可能被载入许多地方,因此也可能被执行许多次。
应该在应用程序文件中,类以外的任何位置设定其初值。例如在main之中或全局函数中,或任何函数之外:
double SavingAccount :: m_rate = 0.0075; //设立static成员变量的初值
请注意,static成员变量的类型也出现在初值设定句中,因为这是一个初值设定操作,而不是一个赋值操作。事实上,static成员变量是在这时候(而不是在类声明中)才定义出来的。如果没有做这个初始化操作,会产生链接错误。
另外,设定static成员变量初值时,不需要考虑m_rate是不是private数据,因为初始化时不受任何存取权限的束缚。
2、static成员变量的存取方式
可以是在没有诞生任何对象实例之前的存取方式:
void main()
{
SavingAccount :: m_rate = 0.0075; //想要这么赋值,必须把m_rate权限改为public。除了初始化操作之外都必须受存取权限的限制
}
也可以在产生一个对象之后:
void main()
{
SavingAccount myAccount;
myAccount.m_rate = 0.0075; //当然这里也要把m_rate权限改为public
}
这里需要区分一下观念:static成员变量除了是类的或对象的一个变量之外,还是脱离对象之外的一个变量。所以既可以跟其他类成员变量一样赋值操作,也可以直接用类来操作,这时候可以想象它是一个全局变量。为了区分static变量,第一种用类赋值的方法比较不容易出错。
3、考虑static成员变量的权限操作
当然,虽然任何函数(包括全局函数或成员函数,static或non-static)都可以存取static成员变量。但是前提是必须考虑成员变量的权限,所以private static成员变量必须设计一个static成员函数:
还是上面的例子:
class SavingAccount
{
private:
char m_name[40]; //存户姓名
char m_addr[60]; //存户地址
double m_total; //存款额
static double m_rate; //利率
public:
static void setRate(double newRate) { m_rate = newRate; }
};
double SavingAccount :: m_rate = 0.0075; //设定static成员变量的初值
void main()
{
SavingAccount :: setRate(0.0074); //直接调用类的static成员函数
或者
SavingAccount myAccount;
myAccount.setRate(0.0074); //通过对象调用staitc成员函数
}
因为static不需要借助任何对象,就可以直接通过类调用执行,所以编译器不会为它暗加一个this指针。也因为如此,static成员函数无法处理类中的non-static成员变量。这是因为前面介绍过,成员函数之所以能够以单一一份函数码处理各个对象的数据而不紊乱,完全是靠的this指针的指示。static成员函数“没有this参数”这种性质。
相关文章推荐
- [C++]继承与面向对象设计
- Dev-C++ 配置SDL开发环境
- 【AKOJ】1198-排排队
- C++11新特性
- C++ Virtual详解
- c语言学生信息管理系统学习感想
- 如何成为一个牛逼的C/C++程序员?
- [c++].类型转换
- C++拾遗(一)基础
- 判断一棵树是否是另一棵树的子树(C语言版)
- C++简单QQ程序服务器端的实现代码
- C++异常处理之abort()、异常机制、exception 类
- First Blog!
- C++::STL::algorithm
- C++第四次上机实验
- C++基础实例(2)
- C++作业四
- 设计模式C++学习笔记之一(Observer观察者模式)
- c++ string类对象排序
- c语言特殊数之和