C++为何需要静态成员函数


结论

先说结论:类有时需要一个与类有关但与所有对象没有直接关系的属性

一般情况下,如果有N个同类的对象,那么每一个对象都分别有自己的成员变量,不同对象的成员变量各自有值,互不相干。但是有时我们希望有某一个或几个成员变量为所有对象共有,这样可以实现数据共享。

可以使用全局变量来达到共享数据的目的。例如在一个程序文件中有多个函数,每一个函数都可以改变全局变量的值,全局变量的值为各函数共享。但是用全局变量的安全性得不到保证,由于在各处都可以自由地修改全局变量的值,很有可能偶然失误,全局变量的值就被修改,导致程序的失败。因此在实际开发中很少使用全局变量。

  • 说人话:村头王寡妇跟前夫孙福贵生了仨孩子,分别叫孙一孙二孙三。几年后她找到了真爱,带着三个孩子嫁给了李有财,自此三个孩子改名为李一李二李三。王寡妇跟孙福贵叮叮当当造小人儿的过程就是实例化了三个名字是“王寡妇的娃”的类(李一李二李三),类里有个叫“姓”的静态成员变量。当王寡妇改嫁时只需改动这个静态成员变量,所有娃的姓就会发生改变。由此可见,这个静态成员变量不与任何一个实例(儿子)有关,这个这个类本身(王寡妇的婚嫁情况)有关。(来自知乎大佬)

  • 举个例子:C++ Primer关于静态成员举了个例子,是说一个银行账户类需要一个数据成员来表示当前的利率。在这个类中,我们所希望的是利率与类相关联,而不是与类的每个对象相关联。这个时候就可以用静态成员函数,可以提高效率,而且一旦利率浮动,每个对象也能相应使用新的值。 还有一些场景是必须用静态成员函数的,普通成员函数会出错…


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

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

普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享。

class CRectangle
{
private:
    int w,h;
    static int nTotalArea;   //静态成员变量
    static int nTotalNumber;
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.nTotalNumber;

在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数。

作者:小水VV
链接:https://www.zhihu.com/question/34018632/answer/858408422
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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 CRectanagle::PrintTotal()
{
    cout<<nTotalNumber<<","<<nTotalArea<<endl;
}
int CRectangle::nTotalNumber = 0;
int CRectangle::nTotalArea = 0;
//必须在定义类的文件中对静态成员变量进行一次说明
//或初始化。否则编译能通过,链接不能通过。
int main()
{
    CRectangle r1(3,3),r2(2,2);
    //cout<<CRectangle::nTotalNumber; //Wrong,私有
    CRectangle::PrintTotal();
    r1.PrintTotal();
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VioletEvergarden丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值