const与指针及函数

const与指针及函数

cppreference-zh-201806 中的简单定义

const 对象——类型为 const-qualified 的对象,或 const 对象的非 mutable 子对象。这种对象不能修改:尝试直接这么做是编译时错误,且尝试间接这么做(例如通过到非 const 类型的引用或指针修改 const 对象)导致未定义行为。

const与指针

声明指针时,在类型前或后都可以使用关键字const,也可在两个位置都使用。例如,下面都是合法的声明,但是含义大不同:

const int * pOne;    //指向整形常量 的指针,它指向的值不能修改
int * const pTwo;    //指向整形的常量指针 ,它不能在指向别的变量,但指向(变量)的值可以修改。 
const int *const pThree;  //指向整形常量 的常量指针 。它既不能再指向别的常量,指向的值也不能修改。

const与函数

《代码大全》说:代码是写给人看到的,我觉得const的设计就出于这个目的。即,通过避免人为的失误来提升程序的健壮性。从这个角度出发,很多设计的合理性就显而易见了。

用const修饰函数的参数

应用背景

我们经常会将自定义类型作为函数参数。如果使用值传递,则会产生临时对象。临时对象的构造、复制、析构过程都将消耗资源。因此,我们会使用引用传递来避免这个开销。引用传递意味着我们可以修改实参的值,我们有时候并不希望这件事发生,需要限制函数体对实参的修改的能力。

应用方法

在引用传递的基础上加上const关键词,即:const A &a。这个语法中兼备了高效和安全。其中,&保证了高效,const缩小了权限,从而保证了安全。

错误的应用
  • void f(const int a) 值传递本身就意味着对形参的修改不会影响实参。写法并非错误,事实上在某些场合也具备意义。但是对于避免影响形参这个目的,是无意义的。
  • void f(const int &a) 像int这样的内部类型作为函数参数被传递时,不存在构造、复制、析构的过程,复制的速度非常快。这种写法和void f(int a)的效率几乎相当。写法并非错误,事实上在某些场合也具备意义。但是对于安全又高效地使用实参这个目的,是无意义的。

用const修饰函数的返回值

申明格式为const A* GetA(void);。和上一节同理,也是为了更安全地使用&。引用传递返回值一般出现在链式表达中,const则限制了不正常的链式表达。

程序举例:

class A
{
    A& operate = (const A &other);// 赋值函数
};

int main(){
    A a, b, c; // a, b, c 为A的对象
    a= b = c; // 正常的链式赋值
    (a= b) = c; // 不正常的链式赋值,但合法。如果将赋值函数的返回值加const修饰,那么该返回值的内容不允许被改动。语句a= b = c 仍然正确,但是语句(a= b) = c 则是非法的。

    return 0;
}

用const修饰成员函数

申明格式举例:int C::f(void) const;。作用是:f函数不可以修改数据成员,或者调用其它非const成员函数。

程序举例:

class Stack
{
    public:
    void Push(int elem);
    int Pop(void);
    int GetCount(void) const; // const 成员函数
    private:
    int m_num;
    int m_data[100];
};
    int Stack::GetCount(void)const  
{
    ++ m_num; // 编译错误,企图修改数据成员m_num
    Pop();// 编译错误,企图调用非const函数
    return m_num;
}

为什么const放在后面?因为const在修饰成员函数时,其实修饰的是*this。而this没有显式地写出来,所以就放在后面了(个人理解)。

如果调用了非const成员函数,VS2017会报类似于这样的错误:

error C2662: “CDate::COMPARE CDate::comparef(CDate,const CDate &)”: 不能将“this”指针从“const CDate”转换为“CDate &”

注意:const不能修饰静态成员函数。而静态成员函数属于类而非对象,因此不可以被const修饰。

参考来源

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值