c++类的静态成员踩坑记录

原创 2015年11月19日 21:40:59

今天在静态成员上踩坑不少,特此记录。

c++类的静态成员需要在类内声明,而在类外进行定义,如下

class M
{
public:
    static int m;
};
int M::m = 90;
int main()
{
    cout<<M::m;
}

类内静态常量可以在类内直接初始化,如下,当然也可用上面的方法

class M
{
public:
    const static int m = 9;
};

int main()
{
    cout<<M::m;
}

类内静态常量数组的定义

class M
{
public:
    const static int m[];//声明
    M()
    {
        cout<<m[2]<<endl;
    }
};

const int M::m[8]={0,9,8,8};//定义

int main()
{
    M m = M();
}

那么问题来了,可不可以直接定义呢?静态常量数组也是常量啊,当然可以

class M
{
public:
    static const int m[] = {2,3,4};
    M()
    {
        cout<<m[2]<<endl;
    }
};

int main()
{
    M m = M();
}

如果你把上面代码copy或者敲下来编译会发现有个错误:
In-class initializer for static data member of type ‘const int [78]’ requires ‘constexpr’ specifier
大概意思是:const int [ 3 ]的静态数据成员初始化需要constexpr类
为什么呢?
因为const只表明这个变量是的值是不变的,但并没表明该变量需要在编译期确定,巧的是,数组就恰恰需要在编译期确定,而constexpr,则表明这个值不仅是值不变的,而且也是编译期确定的。
那好,我们改

class M
{
public:
    static constexpr int m[] = {2,3,4};
    M()
    {
     //   cout<<m[2]<<endl;  注意这句注释,往下看
    }
};

int main()
{
    M m = M();
}

没错,编译是成功的,那么,把上面的注释去掉呢,铛,两个错误来袭。。。
clang: error: linker command failed with exit code 1 (use -v to see invocation)
链接器命令失败,退出码1(使用- v查看调用)
“M::m”, referenced from:

查了好多问答文章,没有找到此错误原因,回过头再看书(c++primer),看到这样一段话:

class A {
static constexpr int p = 30;
double d[p];
};
如果某个静态成员的应用场景仅限于编译器可以替换它的值的情况,则一个初始化的const或constexpr static不需要分别定义。相反,如果我们将它用于值不能替换掉应用场景中,则该成员必须有一条定义语句。

显然,静态常量数组的元素是不能被替换掉的,所以。。。

class M
{
public:
    static constexpr int m[] = {2,3,4};
    M()
    {
        cout<<m[2]<<endl;
    }
};

constexpr int M::m[];//如果在类的内部提供了一个初始值,
                    //则成员的定义不能再指定一个初始值了

int main()
{
    M m = M();
}

以上,就是今一下午踩坑的收获,刚出坑,脚下难免有泥,若有错误,欢迎批评指正!

版权声明:本文为博主原创文章,转载请附上链接http://blog.csdn.net/to_be_better

相关文章推荐

c++11中的lambada表达式

C++11添加了一项名为lambda表达式的新功能,通过这项功能可以编写内嵌的匿名函数,而不必编写独立函数和函数对象,使得代码更容易理解。 lambda表达式的语法如下所示: [captu...

C++11学习笔记(1) —— auto

C++11 的到来又为C++注入了新鲜的血液,更严格的类型检查,新的功能特性以及新收录的STL,都使得C++11更为安全和高效。笔者将C++11的学习过程记录下来,不对之处还望指正。 IDE: vs...

问题记录:cocos2dx-C++静态成员函数的使用问题

/** Time: 2013-0818 Requirements: 1. 解决C++使用静态成员函数,编译后运行出错的问题;   */   情景:有class A,它只有一个共享方法生成一个实例,又有...
  • qimuya
  • qimuya
  • 2013年08月28日 14:39
  • 1625

C++友元关系和类的静态成员概念和使用

一:C++友元关系: 1.类对于成员的封装(public, private, protected)     1).封装性的优势:         有效地保护了对象的内部细节,使得对象的使用和对象...

面向对象c++静态成员的使用

  • 2011年04月23日 21:08
  • 396B
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c++类的静态成员踩坑记录
举报原因:
原因补充:

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