cpp——与c之不同——static const

来源:互联网 发布:第一行代码 json 解析 编辑:程序博客网 时间:2024/06/05 08:59

static

c

static在c中是一个多义词,可修饰全局对象和局部对象
  • 修饰全局对象:对应中文为"内部的",修饰对象作用域
  • 修饰局部对象:对应中文为"静态的",修饰对象存储方式(生命周期)

static全局对象

static int g_static_food = 5;  //static全局数据对象定义static void feed(int rice, int meat);  //static全局函数对象声明static void feed(int rice, int meat) { printf("feed rice and meat\n"); }  //static全局函数对象定义

static局部对象

void feed(){    static int l_static_food = 5;  //static局部数据对象定义}

c++

c++对c static功能进行了保留,并未做任何改变,但扩展了static功能,扩展的static功能主要用于:
  • static数据成员:不属于this成员
  • static函数成员:无this隐含参数
class CAnimal{private:    static int totalGroup;    public:    static int getTotalGroup();};int CAnimal::totalGroup = 5;int CAnimal::getTotalGroup(){    return totalGroup;}

const

c

const对象可不初始化,未初始化的const对象值无意义(无值且值不可修改)
c之所以允许const对象可不初始化(未初始化的const对象值无意义)是因为struct(union)无构造函数,如果const对象必须初始化且struct(union)有const成员对象,则必须对整个struct(union)对象初始化,这与普通对象(普通成员对象)可不初始化矛盾,因此const对象可不初始化是c的无奈妥协
struct Animal{    int age;    int color;    const int food;};void use_const(){    int const ci;    int* const cpi;    struct Animal animal;        printf("ci = %d\n", ci);    printf("cpi = %p\n", cpi);    printf("animal.age = %d, animal.color = %d, animal.food = %d\n", animal.age, animal.color, animal.food);}
output:
ci = 1606416504cpi = 0x12068animal.age = 73832, animal.color = 512, animal.food = 515
注:const对象与普通对象一样,未初始化无值(非默认0值)

c++

const对象必须初始化,因为class(struct&union)含构造函数,构造函数是初始化行为,如果class(struct&union)含const数据成员对象,可通过构造函数初始化
const对象必须初始化保证了const对象值有意义(初值且值不可修改)
void use_const(){    int i = 5;        //int const ci1;    int const ci2 = i;        //int* const cpi1;    int* const cpi2 = &i;        printf("ci = %d\n", ci2);    printf("cpi = %p\n", cpi2);}

修饰引用

引用本质是const对象,类型为指针,const引用的const修饰引用的类型,因此const引用本质是const对象,类型为const指针(指向const对象)
  • int& ri等价于int* const ri
  • const int& rci等价于 const int* const rci
void const_ref(){    int i = 5;    const int ci = 8;        int& ri1 = i;    //int& ri2 = ci;        const int& rci1 = i;    const int& rci2 = ci;}

const修饰类

const修饰类,可修饰类的部分有:
  • non-static数据成员:必须在构造函数显式初始化,即在构造函数初始化列表的初始化式中显式初始化,不能进行默认初始化(不能omit),自此const non-static数据成员不可修改
  • non-static函数成员:const修饰this,常规this类型为classname* const this,const修饰后为classname const* const this,因此不可修改实例对象this数据成员(non-static数据成员,属于this成员),不可调用non-static函数成员(this传递时,classname const*不能转classname*)
  • static数据成员:不可修改staitc数据成员
class CFood{public:    int foodid;    public:    CFood() : foodid(0) { cout << "CFood()" << endl; }    public:    CFood(int fid) : foodid(fid) { cout << "CFood(int)" << endl; }    public:    ~CFood() { cout << "~CFood()" << endl; }};class CAnimal{private:    int const cColor;    int color;    private:    CFood const cFood;    CFood food;    public:    CAnimal();    public:    ~CAnimal();    public:    void init() const;    public:    void info();    private:    static int const totalGroup;    public:    static int getTotalGroup();};int const CAnimal::totalGroup = 5;CAnimal::CAnimal() : cColor(5), cFood(5){    //cColor = 5;    color = 8;    //cFood.foodid = 5;    food.foodid = 8;    //totalGroup = 58;        cout << "CAnimal()" << endl;}CAnimal::~CAnimal(){    //cColor = 5;    color = 8;    //cFood.foodid = 5;    food.foodid = 8;    //totalGroup = 58;        cout << "~CAnimal()" << endl;}void CAnimal::init() const{    //cColor = 5;    //color = 8;    //cFood.foodid = 5;    //food.foodid = 8;    //totalGroup = 58;        cout << "init()" << endl;}void CAnimal::info(){    //cColor = 5;    color = 8;    //cFood.foodid = 5;    food.foodid = 8;    //totalGroup = 58;        cout << "info()" << endl;}int CAnimal::getTotalGroup(){    //totalGroup = 58;        cout << "getTotalGroup()" << endl;        return totalGroup;}void use_const_with_class(){    {        cout << "-----normal instance object-----" << endl;        CAnimal animal;        animal.init();        animal.info();        animal.getTotalGroup();    }        {        cout << "-----const instance object-----" << endl;        CAnimal const canimal;        canimal.init();        //canimal.info();        canimal.getTotalGroup();    }}
output:
-----normal instance object-----CFood(int)CFood()CAnimal()init()info()getTotalGroup()~CAnimal()~CFood()~CFood()-----const instance object-----CFood(int)CFood()CAnimal()init()getTotalGroup()~CAnimal()~CFood()~CFood()
总结:
  • 构造函数和析构函数不能定义为const函数,因为构造函数和析构函数设计本意就是用来改变对象状态的,定义为const函数与构造函数和析构函数设计本意矛盾
  • const non-static非类类型数据成员必须在构造函数显式初始化,即在构造函数初始化列表的初始化式中显式初始化,不能进行默认初始化(omit),本质就是const对象必须初始化(有初值),自此const non-static非类类型数据成员不可修改
  • const non-static函数成员的本质是修饰this隐含参数,使this实例对象状态不可修改,因此const non-static函数成员不可修改自身状态(non-static数据成员),static数据成员不属于this成员,因此不受const non-static函数成员的const影响
  • static函数成员不能定义为const函数,因为static函数成员无this隐含参数,const不知道修饰谁
  • const类型指针不能转非const类型指针,反之,非const类型指针可转const类型指针,即classname const*不能转classname*,但classname*可转classname const*,因此const实例对象只能调用const non-static成员函数,非const实例对象可调用const non-static成员函数和non-const non-static成员函数
  • 尽管构造函数和析构函数不能定义为const函数,而const实例对象只能调用const non-static成员函数,但const实例对象可调用构造函数和析构函数,否则const实例对象就无法构造和析构了
0 0