【第22期】观点:IT 行业加班,到底有没有价值?

C++:类内static成员

原创 2015年07月07日 20:53:59

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'|

触发重定义错误。

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

C++基础--static静态成员

1. 静态局部对象静态局部对象是位于函数内的静态变量,在调用函数前就被创建并赋初值,在程序结束前都不会被撤销,在函数多次调用过程中持续存在并保持它的值。 在头文件中定义静态变量不可行。因为如果在使用...

C++ VS C#(12):函数的重载,类成员的static修饰,属性

//=====================================================================//TITLE:// C++ VS C#(12):函数的重载,类成员的static修饰,属性//AUTHOR:// norains//DATE:// Mond...

程序员升职加薪指南!还缺一个“证”!

CSDN出品,立即查看!

C/C++——为什么类的静态成员函数在定义的时候不写static?

解释一:举个例子,Base是一个类,data是他的int型static数据成员,那么我们这么定义:int Base::data = 10;1、因为使用static数据成员时,都是Base::data。...

为什么static数据成员一定要在类外初始化?

为什么static数据成员一定要在类外初始化? 1.避免重复定义和初始化 <>说在类外定义和初始化是保证static成员变量只被定义一次的好方法。 但,为什么static const int就可以在类里面初始化呢? 想起C中一个函数里定义一个static变量是为了保证...

C++主题——static类成员

C++主题——static类成员1.用static可以为类类型的所有对象所共有,像是全局对象,但又被约束在类类型的名字空间中。2.可以实施封装,将其放在private或protected区域中。3.s...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)