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

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 = 1606416504
cpi = 0x12068
animal.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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值