【C/C++】类中的const成员 static成员

来源:互联网 发布:淘宝well运动正吗 编辑:程序博客网 时间:2024/05/21 00:16

const 数据成员


const 数据成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其 const 数据成员的值可以不同。所以不能在类声明中初始化 const 数据成员,因为类的对象未被创建时,编译器不知道const 数据成员的值是什么。

 const 数据成员的初始化只能在类的构造函数的初始化表中进行。要想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现,或者static const。




static 数据成员


static 数据成员目的是作为类作用域的全局函数,被类里的所有对象共享,即是没有创建任何对象,该成员也存在。static成员变量不能在构造函数初始化列表中初始化,因为它不属于某个对象。在类的内部只是声明,定义必须在类定义体的外部,通常在类外定义时初始化,或者使用静态函数初始化。借用 gcc 的话:ISO C++ forbids in-class initialization of non-const static member

注意:static 成员变量的内存空间既不是在声明类时分配,也不是在创建对象时分配,而是在编译时在静态数据区分配内存,到程序结束时才释放。



const static 数据成员


const static 数据成员被一个类的所有对象共享,常量,可以在类内定义处初始化,也可以在类外初始化。




const 成员函数


const 成员函数主要是防止修改对象的成员变量(mutable 修饰的成员变量,static 变量除外)。即const成员函数不能修改成员变量的值,但可以访问成员变量。注意 const 成员函数只能保证不修改当前 this 指针所指的对象的成员变量,若通过参数传递进来有别的对象名,是可以修改其成员变量的,还有就是在 const 成员函数里通过 const_cast 移除 *this 的 const 特性后调用一些非 const 成员函数也有可能会改变 *this 对象的成员变量,虽然这种做法其实是错误的。




static 成员函数


static成员函数主要目的是作为类作用域的全局函数,不能访问类的非静态数据成员。类的静态成员函数没有this指针,这导致:

1、静态成员函数可以直接访问类的静态数据和函数成员,而访问非静态成员必须通过参数传递的方式得到一个对象名,然后通过对象名来访问,与其不同的是非静态成员函数可以任意地(非)静态成员函数和(非)静态数据成员;

2、不能被声明为virtual。


注意: 与数据成员不同,static 与 const 不能同时修饰成员函数

原因:const 修饰符用于表示函数不能修改成员变量的值,该函数必须是含有 this指针 的类成员函数,函数调用方式为 __thiscall ,而 static 函数是不含有 this指针 的,调用规约是 __cdecl 或 __stdcall ,两者是冲突的。


下面来一个完整的例子:

#include <iostream>using namespace std;class boy{public:boy(int _a):a(_a){}                  //常量初始化static int Init();                   //静态成员函数声明,只能访问静态数据成员void display() const;                //const成员函数声明void test();static void say();const int a;                         //常量定义static int b;                        //静态变量声明const static int c = 3;              //类内定义+初始化静态常量,与 static const int c = 3 一个意思};int boy::b = boy::Init();                            //静态函数初始化静态变量//int boy::b = 2;                                    //类外定义+初始化静态变量,不用加 static, public, pirvate 等修饰//const int boy::c = 3;                              //类外定义+初始化静态常量,不用加 static, public, private 等修饰int boy::Init(){return c;}void boy::display() const                             //关键字 const 必须用同样的方式重复出现在函数定义处{cout << a << " " << b << " " << c << endl;}void boy::test()                                      //非静态成员函数,可直接访问(非)静态数据成员与(非)静态成员函数{cout << a << " " << b << " " << c << endl;display();say();}void boy::say()                                       //静态成员函数,可直接访问静态数据成员与静态成员函数{cout << b << " " << c << endl;}int main(){boy b(1);boy d(2);cout << b.a << " " << b.b << " " << b.c << endl; //通过对象访问静态数据成员,同理也可通过对象访问静态成员函数cout << boy::b << " " << boy::c << endl;         //通过类访问静态数据成员b.display();   cout << &b.b << " " << &d.b << " " << &boy::b << endl;  //静态数据成员共享同一内存b.test();                    return 0;}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 二建有效期到了怎么办 二级建造师到期怎么办 网上选车牌号后怎么办 政府拖欠水利工程款怎么办 重庆造价员到期了怎么办 枕大神经发炎怎么办 塑钢推拉窗下沉怎么办 网上买东西数量不够怎么办 淘宝买东西数量不够怎么办 康佳遥控器坏了怎么办 电视机频幕脏了怎么办 极米遥控器失灵怎么办 电视遥控坏了怎么办 小米手机触摸屏失灵怎么办 oppo手机触摸屏失灵怎么办 苹果手机屏幕没反应怎么办 苹果6sp换屏卡顿怎么办 苹果4屏幕失灵怎么办 苹果手机老是卡怎么办 苹果手机卡机了怎么办 苹果手机卡屏了怎么办 苹果8手机老卡机怎么办 苹果手机不开机怎么办 手机开机后黑屏怎么办 苹果x手机黑屏怎么办 苹果7手机黑屏怎么办 苹果触控不灵敏怎么办 收银机触屏失灵怎么办 手机屏一半失灵怎么办 苹果六手机屏幕失灵怎么办 苹果5s卡怎么办 苹果5很卡怎么办 笔记本屏幕卡顿怎么办 手机外屏幕失灵怎么办 6p手机屏幕失灵怎么办 home键指纹失灵怎么办 小米触屏不灵敏怎么办 vivo手机音量小怎么办 iphone尾插松动怎么办 充电头接触不良怎么办 苹果充电口松动怎么办