C++:类内static成员

static成员是与类相关的,而不是与类的各个对象保持关联。

实际上,这在一定程度上减少了资源开销。

想象类内某const int size,每个对象的值都应当是相同的,如果单纯的将其定义为const成员,那么每一个对象都会有一个size的副本,浪费资源。

由于类内static是整个类的所有对象共享,所以它没有this指针

由于是类内static,所以static也会有不同的访问权限。

public static

static data and static function

这种用法并不常见,看下面的例子:

`#include <iostream>
using namespace std;
class Test
{

public:
    static int x;
    static void fun(){
        cout << "Calling public static function fun()" << endl;
    }
};

int Test::x = 10;//类内声明,类外定义

int main()
{
    Test test;

    cout << Test::x << endl;
    cout << test.x << endl;
    test.fun();
    Test::fun();
    return 0;
}

其中x和fun()是static成员,访问权限是public。这意味着该类的对象从类外即可轻松访问x和fun()。
注意这里强调,static function 是没有this指针的,所以test.fun()实际上只是通过test调用了Test类的fun(),和test并无关系。
test.x同理。
可见这种调用方式可能会产生歧义,因此更建议使用ClassName::static data的调用方式。

private static

private static是最为常用的方式。
因为访问权限是static,所以有很好的封装性。对于类内经常用到的操作,可以将其抽象成一个工具函数(tool function)方便使用
,因为这个tool function是属于整个类的,因此将其编写为static更能节省空间。

#include <iostream>
using namespace std;

class Test
{
private:
    static int maxSize;
    static void toolFunction();//do something in the class
public:
    static void accessMaxSize(); 
};
int main()
{
    Test test;

    return 0;
}

maxSize是private data,那么以前的test.maxSizeTest::masSize这两种用法都不能访问maxSize
对于这种数据想要完成访问操作,需要定义一个public static method,正如类中的static void accessMaxSize()

static const 成员

这里是比较容易弄混的地方,看下面这个例子。

#include <iostream>
using namespace std;

class Test
{
private:
    static const int maxSize = 5;
    int array[maxSize];
public:
    Test(){
    cout << &maxSize << endl;
    }

};

int main()
{
    Test test;

    return 0;
}

Test类中声明了一个static const int maxSize,并且赋予初值,作为成员array[]的长度参数,直到这里一切都OK,但是
你会发现,上述代码无法通过编译。

编译器提示
**undefined reference toTest::maxSize’|**`

使用未定义的成员?
等等?我们不是给予了初值了吗?
实际上,如果去掉上述代码的构造函数部分的cout << &maxSize << endl;语句编译器就会开心的放你通过。

这很奇怪,为什么对maxSize取地址编译器就报错呢?
这意味着编译器没有给maxSize分配空间,也就是说,maxSize未定义!

Effective C++ 是这样解释的:

我们看到的static const int maxSize = 5是一个声明式而非定义式。c++要求对任何一个东西提供定义式,但是如果是class专属常量且为static且为integral(ints,chars,bools),则需特殊处理,只要不取它的地址,编译器一切都ok。

最好的解决办法是,在类外提供一个定义式

const int Test::maxSize;

需要注意的是,不要const int Test::maxSize = someValue,即便这个someValue是5也不可以,编译器会提示

error: duplicate initialization of 'Test::maxSize'|

触发重定义错误。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值