const:常量,不变的

mutable:易变的

从意思上理解,可见const和mutable是一对反义词,它们都是C++的关键字。

const成员函数不能修改调用它的对象。类的成员函数可以被声明为const,这将使得函数的隐式参数this将被作为const类型的指针。这也就意味着一个const成员函数不能修改调用它的对象。而且,const对象不能调用非const成员函数。然而,const对象和非const对象都可以调用const成员函数。

要将一个成员函数声明为const,可以使用下面的形式:

 C++ Code 
1
2
3
4
5
6
 
class X
{
    int some_var;
public:
    int f1() const;    //const成员函数
};

可以看到,关键字const被放在函数声明之后。将一个成员函数声明为const的目的是防止函数修改调用它的对象。例如下面的代码:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
#include <iostream>
using namespace std;

//说明const函数的用法,这个程序不能通过编译
class Demo
{
    int i;
public:
    int get() const
    {
        return i;        //正确
    }
    void seti(int x) const
    {
        i = x;          //错误!
    };
};

void main()
{
    Demo ob;
    ob.seti();
    cout << ob.get() << endl;
}

上面的这个程序不能通过编译,因为函数seti()被声明为const成员函数,这意味着在函数中不能修改调用函数的对象。但是由于seti()试图修改成员变量i,所以程序会产生错误,而在函数geti()中并不修改成员变量i,所以这个函数是正确的。

有时你可能想在const函数中修改类的某些成员,但又不想让函数修改类的其它成员,那么可以通过关键字mutable来实现这种功能。mutable将覆盖const属性。也就是说,在const成员函数中可以修改mutable成员,例如:

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
#include <iostream>
using namespace std;

//可以通过编译,运行正确
class Demo
{
    mutable int i;
public:
    int get() const
    {
        return i;                //正确
    }

void seti(int x) const
    {
        i = x;                  //错误!Maybe
    };
};

void main()
{
    Demo ob;
    ob.seti();
    cout << ob.get() << endl;
}

//运行结果

在上面的程序中,类的成员变量i被定义为mutable,所以在函数seti()中可以修改它的值。

const成员变量的初始化

在构造函数中对成员变量进行初始化是很普遍的初始化方法,然而,这种方法并不是适用于所有情况,例如:如果在类的定义中使用了const来声明成员变量,那么在类的构造函数中将不能对这些成员变量赋初始值,因为const变量必须在构造函数调用之前被初始化,在使用"引用类型的成员"以及"没有默认构造函数的成员"时存在着同样的问题,因为这些成员必须首先被初始化。为了解决这个问题,在C++中定义了一种成员初始化语法,可以在创建对象时为类的成员指定初始值。

成员初始化语法 类似于 调用基类构造函数的语法,它的通用形式如下所示:

 C++ Code 
1
2
3
4
5
6
7
 
constructor(arg_list)
    : member(initlalizer)
    , member(initlalizer)
    , member(initlalizer)
{
    //构造函数体
}

在构造函数的后面指定你想要初始化的成员,同时用冒号将构造函数的名字和参数列表分开。也可以将基类构造函数的调用和成员的初始化放在同一参数列表中。

[转]C++类成员修饰const和mutable的更多相关文章

  1. python - 类成员修饰符

    在java,c#类的成员修饰符包括,公有.私有.程序集可用的.受保护的. 对于python来说,只有两个成员修饰符:公有成员,私有成员 成员修饰符是来修饰谁呢?当然是修饰成员了.那么python类的成 ...

  2. C#基础--类/接口/成员修饰符,多态、重载、重写,静态和非静态

    C#基础--类/接口/成员修饰符,多态.重载.重写,静态和非静态 类/接口/成员修饰符 C#修饰符---接口: 接口默认访问符是internal接口的成员默认访问修饰符是public C#修饰符--类 ...

  3. Python_day8_面向对象(多态、成员修饰符、类中特殊方法、对象边缘知识)、异常处理之篇

    一.面向对象之多态 1.多态:简而言子就是多种形态或多种类型 python中不支持多态也用不到多态,多态的概念是应用与java/C#中指定传参的数据类型, java多态传参:必须是传参数的数据类型或传 ...

  4. Python菜鸟之路:Python基础-类(2)——成员、成员修饰符、异常及其他

    三大成员 在Python的面向对象中,主要包括三大成员:字段.方法.属性 字段 类成员的字段又可分为普通字段.静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,代码示例如下: ...

  5. Python面向对象之成员修饰符

    对于这些类成员有修饰符 之前定义字段country任何对象都可以访问,是公有的 可以定义为私用属性,只有类内部的方法可以调用,外部不能直接调用,但是可以间接调用 vim day7-10.py #!/u ...

  6. const修饰的成员是类成员,还是实例成员?

    很抱歉,我以为只有static修饰的成员是类成员,可以通过类名直接访问,然而,const 修饰的成员也属于类成员,直接通过类名访问,不能通过实例变量访问. 做维护久了,深刻的理解,扎实的基础对写出高质 ...

  7. 【c++】类中的const成员

    const成员变量 举个例子 #include <iostream> using namespace std; class A { public: A(int size) : SIZE(s ...

  8. const与static类成员

    const成员函数作用1. 不能修改类的成员变量,同时不能调用类的非const成员函数.(const成员函数中,this的类型是一个指向const类类型对象的const指针,const成员函数返回*t ...

  9. const型类成员

    一.关于const类成员函数有以下几个需要注意的地方: 1. 在普通的非const成员函数中,this的类型是一个指向类类型的const指针,而const成员函数中,this的类型是一个指向const ...

随机推荐

  1. Free Professional Resume Examples and Writing Tips

    https://www.thebalancecareers.com/free-resume-examples-and-writing-tips-2063596 Do you need to write ...

  2. hdu2281&&POJ1320——Pell方程

    hdu2281 输入一个 $N$,求最大的 $n$($n \leq N$)和 $x$,使得 $x^2 = \frac{1^2+2^2+...+n^2}{n}$. 分析: 将右边式子的分子求和化简,有: ...

  3. Windbg Assembly Code(反汇编)窗口的使用

    在WinDbg中,可以通过输入命令(u, ub, uu (Unassemble))或使用反汇编窗口查看程序汇编代码. 如何打开 DissAssembly Code窗口 通过菜单View-->Di ...

  4. 链接指示:extren"C"

    C++程序有时需要调用其他语言编写的函数,最常见的是调用C语言编写的函数.像所有其他名字一样,其他语言中的函数名字也必须在C++中进行声明,并且该声明必须指定返回类型和形参列表.对于其他语言编写的函数 ...

  5. TCP/IP协议总结

    TCP/IP网络协议栈分为四层, 从下至上依次是: 链路层 其实在链路层下面还有物理层, 指的是电信号的传输方式, 比如常见的双绞线网线, 光纤, 以及早期的同轴电缆等, 物理层的设计决定了电信号传输 ...

  6. 洛谷 P4427

    传送门 洛谷P4427 题意: 给你一个数,然后让你求这两个数之间的点的深度的k次方和. #思路: 很容易想到lca.因为lca可以说是求树上两个点的距离的好方法.而且lca还能遍历每一个点. 然后我 ...

  7. CSRF 跨站

    目录 CSRF 跨站请求伪造 解决跨站伪造问题: csrf 相关的装饰器: csrf.js文件: CSRF 跨站请求伪造 CSRF全称为Cross-site request forgery,也被称为: ...

  8. 动态的src路径怎么写

    错误写法 <div class="icon--wrapper" @click="before"> <img class="icon- ...

  9. java 查找指定包下的类

    package com.jason.test; import java.io.File; import java.io.IOException; import java.io.UnsupportedE ...

  10. pandas 获取不符合条件的dataframe

    pandas 获取不符合条件的dataframe 或将其过滤掉: df[df["col"].str.contains('this'|'that')==False] >> ...