美文网首页
静态成员变量和静态成员函数

静态成员变量和静态成员函数

作者: 波洛的汽车电子世界 | 来源:发表于2019-05-04 17:16 被阅读0次

注:以下大部分内容来源于 coursera 课程《C++程序设计》

  1. 静态成员:在定义前加了关键字static 的成员
  2. 包括静态成员变量和静态成员函数
  3. 与普通成员的差别:普通成员变量每个对象有各自的一份,静态成员变量一共就一份,为所有对象共享。sizeof()不会计算静态成员变量。
  4. 普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用于某个对象。
  5. 静态成员不需要通过对象就能访问。
  6. 静态成员变量本质上是全局变量,不依靠于对象。静态成员函数是全局函数。

如何访问静态成员?

  1. 通过类名::成员名
    Crectangle:PrintTotal();
  2. 对象名.成员名
    Crectangle r;
    r.PrintTotal();
    注意:虽然这里是r.PrintTotal,但是PrintTotal并不是作用在r上面的,这只是一种形式。
  3. 指针->成员名
    Crectangle *p = &r;
    p->PrintTotal();
  4. 引用->成员名
    Crectangle &re = r;
    int f = re.nTotalNumber;

例子:

考虑一个需要随时知道矩形总数和总面积的图形处理程序,可以用全局变量来记录总数和总面积。
思路:将nTotalNumber++写在构造函数里面,只要有矩形对象的生成,就会自动调用构造函数。
将nTotalNumber--写在析构函数里面,只要有矩形对象的消亡,就会自动调用析构函数。

class CRectangle{
private :
int w,h;
static int nTotalArea;
static int nTotalNumber;
public:
CRectangle(int w_,int h_);
~CRectangle();
static void PrintTotal();
};
//构造函数
CRectangle::CRectangle(int w_, int h_)
{
w=w_;
h=h_;
nTotalNumber++;
nTotalArea += w*h;
}
//析构函数
CRectangle::~CRectangle(){
nTotalNumber--;
nTotalArea -= w*h;
}
void CRectangle::PrintTotal()
{
cout<<nTotalNumber<<","<<nTotalArea<<endl;
}
//声明静态成员变量
int CRectangle::nTotalNumber = 0;
int CRectangle::nTotalArea = 0;
int main(){
CRectangle r1(2,2), r2(3,3);
//cout << CRectangle::nTotalNumber; // Wrong , 私有
CRectangle::PrintTotal();
r1.PrintTotal();
return 0;

}

  • 在C++里面,静态成员变量你必须拿到所有的函数外面来单独的给它声明一下。 必须在定义类的文件中对静态成员变量进行一次说明或初始化。否则编译能通过,链接不能通过。
  • 在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数。
void CRectangle::PrintTotal()
{
cout<<w<<nTotalNumber<<","<<nTotalArea<<endl;
//w是非静态成员变量,不能访问,此条语句错误。
}

*缺陷:忽略了复制构造函数。
在使用CRectangle类时,有时会调用复制构造函数生成临时的隐藏的CRectangle对象。

//构造函数
CRectangle::CRectangle(int w_, int h_)
{
w=w_;
h=h_;
nTotalNumber++;
nTotalArea += w*h;
}
//析构函数
CRectangle::~CRectangle(){
nTotalNumber--;
nTotalArea -= w*h;
}

这个构造函数里面,对TotalNumber和TotalArea进行增加,这是没问题的。但是并不是所有的CRectangle的对象都会用这个构造函数来初始化。 有可能有一些CRectangle的对象,它是用复制构造函数来初始化的,
例子1: 如果调用了一个以CRectangle对象作为形参的函数的时候,这个形参对象就是由复制构造函数初始化的。
例子2:调用了一个以CRectangle对象作为返回值的函数的时候,那这个返回值对象它也是用复制构造函数初始化的。
这样的对象它们生成的时候并没有走构造函数,也就是并没有增加TotalNumber和TotalArea, 但它们在消亡的时候,却一定要走析构函数,就会减掉TotalNumber和TotalArea, 所以这个时候问题就产生了,就会发生总数和这个总面积比实际的情况要少的情况。
例子3: 临时对象在消亡的时候也会调用析构函数。
如果一个函数的返回值是一个对象的话,那这个函数的返回值就是一个临时对象。

  • 解决办法: 为CRectangle类编写一个复制构造函数。
    我们自己写一个复制构造函数,在这个复制构造函数里面,除了我们做复制的工作以外,还要对这两个总数进行修改。

相关文章

  • C++——静态成员函数与静态成员变量

    静态成员函数与静态成员变量使用static进行定义。 静态成员函数和静态成员变量其实就是全局函数与全局变量。 静态...

  • C++——静态成员函数与静态成员变量

    静态成员函数与静态成员变量使用static进行定义。 静态成员函数和静态成员变量其实就是全局函数与全局变量。 静态...

  • C++静态成员与友元

    静态成员 静态变量的初始化(如何定义) static int getnum()//静态成员函数 静态成员函数只能操...

  • 18-static成员

    静态成员(static) 静态成员:被static修饰的成员变量/函数,可以称为静态成员。 可以通过对象(对象.静...

  • 类型转换、static成员、单例模式

    静态成员(static) 静态成员:被static修饰的成员变量\函数可以通过对象(对象.静态成员)、对象指针(对...

  • c++之静态成员

    静态成员:被static修饰的成员变量\函数 可以通过对象(对象.静态成员)、对象指针(对象指针->静态成员)、 ...

  • static,const,拷贝,友元,模板

    静态成员 static 静态成员:被static修饰的成员变量\函数可以通过对象(对象.静态成员)、对象指针(对象...

  • 内部类

    静态内部类 静态内部类只能调用静态成员变量,不能调用非静态成员变量; 成员内部类 成员内部类和成员变量类似; 局部...

  • [初学C++]静态成员

    静态成员变量和成员函数 在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用。所...

  • C++入门08 --静态成员,单例模式,const成员,引用成员

    静态成员 静态成员:被static关键字修饰的成员变量或者函数; 可以通过对象(对象.静态成员),对象指针(对象指...

网友评论

      本文标题:静态成员变量和静态成员函数

      本文链接:https://www.haomeiwen.com/subject/jymtoqtx.html