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

本文详细介绍了静态成员变量和函数在C++中的概念、用途、访问方式以及静态成员变量与普通成员的区别。通过实例演示了如何避免CRectangle类复制构造函数带来的问题,并探讨了静态成员在类封装全局变量的优势。
摘要由CSDN通过智能技术生成

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

静态成员:在定义前加了static关键字的成员。

class CRectangle
{
private:
    int w, h;
    static int nTotalArea;   //静态成员变量
    static int nTotalNumble;
public:
    CRectangle(int w_, int h_);
    ~CRectangle();
    static void PrintTotal();  //静态成员函数
};

//普通成员变量每个对象都有各自的一份,而静态成员变量一共就一份,为所有对象共享。
//普通成员函数必须具体作用于某个对象,而静态成员函数并不具体作用于某个对象。  
//静态成员不需要通过对象就能访问。  
//sizeof 运算符不会计算静态成员变量
class CMyclass
{
    int n;
    static int s;
};//则sizeof(CMyclass) = 4

//静态成员变量本质上是全局变量,哪怕一个对象都不存在,类的静态成员变量也存在。
//静态成员函数本质上是全局函数。
//设置静态成员机制的目的是将和某些类紧密相关的全局变量和函数写到类里面,看上去像一个整体,易于理解和维护。

如何访问静态成员

1、类名::成员名
CRectangle::PrintTotal();
2、对象名.成员名
CRectangle r; r.PrintTotal();
3、指针->成员名
CRectangle *p = &r; p->PrintTotal();
4、引用.成员名
CRectangle &ref = r; int n = ref.nTotalNumble;

//静态成员示例
//考虑一个需要随时知道矩形总数和总面积的图形处理程序
//可以用全局变量来记录总数和总面积,用静态成员将这两个变量封装进类里面,这样更容易理解和维护。
class CRectangle
{
private:
    int w, h;
    static int nTotalArea;   //静态成员变量
    static int nTotalNumble;
public:
    CRectangle(int w_, int h_);
    //CRectangle(CRectangle &r);
    ~CRectangle();
    static void PrintTotal();  //静态成员函数
};

/*
CRectangle类的缺陷:
在使用CRectangle类时,有时会调用复制构造函数生成临时的隐藏的CRectangle对象,如
1、调用一个以CRectangle类对象作为参数的函数时;
2、调用一个以CRectangle类对象作为返回值的函数时。
临时对象在消亡时会调用析构函数,减少nTotalArea和nTotalNumble的值,可是这些临时对象在生成时却没有增加nTotalArea和nTotalNumble的值。
解决办法:
为CRectangle类写一个调用复制构造函数
*/

CRectangle::CRectangle(int w_, int h_)
{
    w = w_;
    h = h_;
    nTotalNumble++;
    nTotalArea += w * h;
    cout << "构造函数" << endl;
}

/*
CRectangle::CRectangle(CRectangle &r)
{
    w = r.w;
    h = r.h;
    nTotalNumble++;
    nTotalArea += w * h;
    cout << "复制构造函数" << endl;
}
*/

CRectangle::~CRectangle()
{
    nTotalNumble--;
    nTotalArea -= w * h;
    cout << "析构函数" << endl;
}

void CRectangle::PrintTotal()
{
    cout << nTotalNumble << "," << nTotalArea << endl;
}

//在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数
/*
void CRectangle::PrintTotal()
{
    cout << w << "," << nTotalNumble << "," << nTotalArea << endl;   //错误:w是非静态成员变量
}
*/

//必须在定义类的文件中对静态成员变量进行一次说明或者初始化。否则编译能通过,但是链接不能通过。
int CRectangle::nTotalNumble = 0;
int CRectangle::nTotalArea = 0;

int main()
{
    CRectangle r1(3, 3), r2(2, 2);
    //cout << CRectangle::nTotalNumble;  //错误:nTotalNumble为私有成员
    CRectangle::PrintTotal();
    r1.PrintTotal();  //等价于上一条语句

    return 0;
}
/*
输出:
构造函数
构造函数
2,13
2,13
析构函数
析构函数
*/
//完整程序
class CRectangle
{
private:
    int w, h;
    static int nTotalArea;
    static int nTotalNumble;
public:
    CRectangle(int w_, int h_);
    CRectangle(CRectangle &r);
    ~CRectangle();
    static void PrintTotal();
};

CRectangle::CRectangle(int w_, int h_)
{
    w = w_;
    h = h_;
    nTotalNumble++;
    nTotalArea += w * h;
    cout << "构造函数" << endl;
}

CRectangle::CRectangle(CRectangle &r)
{
    w = c.w;
    h = c.h;
    nTotalNumble++;
    nTotalArea += w * h;
    cout << "复制构造函数" << endl;
}

CRectangle::~CRectangle()
{
    nTotalNumble--;
    nTotalArea -= w * h;
    cout << "析构函数" << endl;
}

void CRectangle::PrintTotal()
{
    cout << nTotalNumble << "," << nTotalArea << endl;
}

int CRectangle::nTotalNumble = 0;
int CRectangle::nTotalArea = 0;

int main()
{
    CRectangle r1(3, 3), r2(2, 2);
    CRectangle::PrintTotal();

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值