9.const成员

9.面向对象-封装-const成员


9.1 知识点

知识回顾 常量

常量基本概念
常量是程序执行中值不可改变的变量,多数常量声明时必须初始化。

关键点

  1. 必须初始化
  2. 不能被修改

指针与常量的组合类型

  • 指向常量的指针const 加在 * 前(如 const int* ptr),值不可改,指针指向可改。
  • 指针常量const 加在 * 后(如 int* const ptr),指针指向不可改,值可改。
  • 指向常量的指针常量const 加在 * 前后(如 const int* const ptr),值和指向均不可改

const成员变量

规则及作用和常量知识点一样,唯一需要注意的就是,如果想要从外部传值初始化const成员变量,需要在构造函数的初始化列表中初始化

#pragma once
class Lesson09
{
public:
    //第一种初始化const成员变量的方式
    const int testI = 11;
    //如果有部分成员变量希望在const方法中被修改 那么只需要加上mutable即可 其他的不加就不能被修改
    mutable int testI2 = 20;
    static int testI3;
    //重载
    Lesson09(int testI);
    void Test();
};
#include <iostream>
#include "Lesson09.h"
using namespace std;

int Lesson09::testI3 = 30;

//第二种:构造函数中初始化,只能通过初始化列表的形式初始化 常量const成员
Lesson09::Lesson09(int testI) :testI(testI)
{
    //不能这样初始化 常量const成员 否则报错
    //this->testI = testI;
}

void Lesson09::Test()
{
    cout << this->testI << endl;
    //常量初始化后 不能被修改了 否则报错
    //this->testI = 20;
}
Lesson09 l = Lesson09(99);

//常量初始化后 不能被修改了
//l.testI = 20;//报错

cout << l.testI << endl;//99
cout << l.testI2 << endl;//20

const成员函数

  • 规则:在声明完成员函数后 在后方加上const关键字
  • 作用:
    1. 函数中只能读取成员变量,不能修改成员变量
    2. const对象只能调用const方法,不能调用非const方法
  • 对于类对象来说 它本质上是一个自定义的变量类型声明的对象
    它也是可以作为一个常量
#pragma once
class Lesson09
{
public:
    //第一种初始化const成员变量的方式
    const int testI = 11;
    //如果有部分成员变量希望在const方法中被修改 那么只需要加上mutable即可 其他的不加就不能被修改
    mutable int testI2 = 20;
    static int testI3;
    //重载
    Lesson09(int testI);
    void Test();
    //const成员函数
    //在其中只能读取成员变量 不能修改成员变量
    void Test2() const;
};
#include <iostream>
#include "Lesson09.h"
using namespace std;

int Lesson09::testI3 = 30;

//第二种:构造函数中初始化,只能通过初始化列表的形式初始化 常量const成员
Lesson09::Lesson09(int testI) :testI(testI)
{
    //不能这样初始化 常量const成员 否则报错
    //this->testI = testI;
}

void Lesson09::Test()
{
    cout << this->testI << endl;
    //常量初始化后 不能被修改了 否则报错
    //this->testI = 20;
}

//在其中只能读取成员变量 不能修改成员变量
void Lesson09::Test2() const
{
    cout << testI << endl;
    cout << testI2 << endl;
    //不管成员是常量 还是普通成员 都不能再const函数中进行修改
    //作用:避免在某一个函数中去修改类对象的成员变量
    /*testI = 10;
    testI2 = 20;*/
    //在成员变量前面加上mutable 它就可以在const方法中被修改了
    testI2 = 20;
}
const Lesson09 l2 = Lesson09(100);
//l2.Test();//报错 const对象只能调用const方法,不能调用非const方法
l2.Test2();

mutable关键字

如果我们想要在const方法中修改成员变量,我们可以在声明该变量时,在前面加上mutable关键字

#pragma once
class Lesson09
{
public:
    //第一种初始化const成员变量的方式
    const int testI = 11;
    //如果有部分成员变量希望在const方法中被修改 那么只需要加上mutable即可 其他的不加就不能被修改
    mutable int testI2 = 20;
    static int testI3;
    //重载
    Lesson09(int testI);
    void Test();
    //const成员函数
    //在其中只能读取成员变量 不能修改成员变量
    void Test2() const;
};
//在其中只能读取成员变量 不能修改成员变量
void Lesson09::Test2() const
{
    cout << testI << endl;
    cout << testI2 << endl;
    //不管成员是常量 还是普通成员 都不能再const函数中进行修改
    //作用:避免在某一个函数中去修改类对象的成员变量
    /*testI = 10;
    testI2 = 20;*/

    //在成员变量前面加上mutable 它就可以在const方法中被修改了
    testI2 = 20;
}

总结

const 成员变量

  • 特点:与常量特性一致,修饰指针的规则也与外部场景相同。
  • 初始化方式
    1. 声明时直接定义。
    2. 通过构造函数传值定义,但需使用初始化列表禁止在构造函数体内赋值

const 成员方法

  1. 若函数被 const 修饰,则不可修改成员变量,仅能获取其值。
  2. const 类对象仅能访问 const 方法,无法访问普通成员方法。

mutable 关键字

用于使普通成员变量可在 const 方法中被修改。


9.2 知识点代码

Lesson09.h

#pragma once
class Lesson09
{
public:
    //第一种初始化const成员变量的方式
    const int testI = 11;
    //如果有部分成员变量希望在const方法中被修改 那么只需要加上mutable即可 其他的不加就不能被修改
    mutable int testI2 = 20;
    static int testI3;
    //重载
    Lesson09(int testI);
    void Test();
    //const成员函数
    //在其中只能读取成员变量 不能修改成员变量
    void Test2() const;
};

Lesson09.cpp

#include <iostream>
#include "Lesson09.h"
using namespace std;

int Lesson09::testI3 = 30;

//第二种:构造函数中初始化,只能通过初始化列表的形式初始化 常量const成员
Lesson09::Lesson09(int testI) :testI(testI)
{
    //不能这样初始化 常量const成员 否则报错
    //this->testI = testI;
}

void Lesson09::Test()
{
    cout << this->testI << endl;
    //常量初始化后 不能被修改了 否则报错
    //this->testI = 20;
}

//在其中只能读取成员变量 不能修改成员变量
void Lesson09::Test2() const
{
    cout << testI << endl;
    cout << testI2 << endl;
    //不管成员是常量 还是普通成员 都不能再const函数中进行修改
    //作用:避免在某一个函数中去修改类对象的成员变量
    /*testI = 10;
    testI2 = 20;*/

    //在成员变量前面加上mutable 它就可以在const方法中被修改了
    testI2 = 20;
}

Lesson09_面向对象_封装_const成员.cpp

#include <iostream>
#include "Lesson09.h"
using namespace std;
int main()
{
    #pragma region 知识回顾 常量
    //常量是指在程序执行过程中其值不能被改变的变量,大部分的常量在声明时都必须被初始化
    //关键点:
    //1.必须初始化
    //2.不能被修改
    //指向常量的指针: const在 *前面去添加即可,值不能改,指向可以改
    //指针常量:const在 *后面去添加即可,值可以改,指向不能改
    //指向常量的指针常量:const在 *前后都加,值和指向都不能改了
    #pragma endregion

    #pragma region 知识点一 const成员变量

    //规则及作用和常量知识点一样
    //唯一需要注意的就是
    //如果想要从外部传值初始化const成员变量
    //需要在构造函数的初始化列表中初始化
    Lesson09 l = Lesson09(99);

    //常量初始化后 不能被修改了
    //l.testI = 20;//报错

    cout << l.testI << endl;
    cout << l.testI2 << endl;

    #pragma endregion

    #pragma region 知识点二 const成员函数

    //规则
    //在声明完成员函数后 在后方加上const关键字
    //作用
    //1.函数中只能读取成员变量,不能修改成员变量
    //2.const对象只能调用const方法,不能调用非const方法
    //对于类对象来说 它本质上是一个自定义的变量类型声明的对象
    //它也是可以作为一个常量

    const Lesson09 l2 = Lesson09(100);
    //l2.Test();//报错 const对象只能调用const方法,不能调用非const方法
    l2.Test2();

    #pragma endregion

    #pragma region 知识点三 mutable关键字
    //如果我们想要在const方法中修改成员变量
    //我们可以在声明该变量时,在前面加上mutable关键字

    #pragma endregion

    //总结
    //const 成员变量
    //它和常量的特点是一样的,用来修饰指针规则也和外部一样
    //需要注意初始化方式
    //1.直接在声明时定义
    //2.通过构造函数传值定义,但是需要使用初始化列表的方式进行初始化 不能再里面去写赋值

    //const 成员方法
    //1.函数如果用const修饰,那么在其中就不能去修改成员变量了,只能去获取
    //2.对于const类对象,只能访问其中的const方法,普通成员无法访问

    //mutable关键字
    //让普通成员能够在const方法中被修改
}

9.3 练习题

我们有几种初始化类中 const 成员变量的方法?

  1. 在声明时直接定义 (在类中直接写死)
  2. 通过构造函数的初始化列表进行初始化 (可以通过声明对象时在外部传递进来)

常量对象调用成员函数的编译行为

class Counter {
private:
    int count;
public:
    Counter() : count(0) {}

    void increment() { count++; }

    int getCount() {
        return count;
    }

    int getConstCount() const {
        return count;
    }
};

int main() {
    const Counter c;
    //1. 这行代码是否能编译?为什么?如果不能,如何修改?
    cout << c.getConstCount() << endl;
    //2. 这行代码能否编译?为什么?如果不能,如何修改?
    cout << c.getCount() << endl;
    return 0;
}
  1. cout << c.getConstCount() << endl;
    可以编译成功,因为常量对象 只能访问 标记为 const 的成员函数。

  2. cout << c.getCount() << endl;
    会报错,因为常量对象 无法访问const 成员函数。
    如果想要让它编译,需要在方法声明和定义上添加 const 关键字,例如:

    int getCount() const {
        return count;
    }
    

9.4 练习题代码

Lesson09_练习题.cpp

#include <iostream>

int main()
{
    #pragma region 练习题一
    //我们有几种初始化类中const成员变量的方法?

    //1.在声明时直接定义(在类中直接写死)
    //2.通过构造函数的初始化列表进行初始化(可以通过声明对象时在外部传递进来)
    #pragma endregion

    #pragma region 练习题二
    //class Counter {
    //private:
    //    int count;
    //public:
    //    Counter() : count(0) {}

    //    void increment() { count++; }

    //    int getCount() {
    //        return count;
    //    }

    //    int getConstCount() const {
    //        return count;
    //    }
    //};

    //int main() {
    //    const Counter c;
    //    //1.这行代码是否能编译?为什么?如果不能,如何修改?
    //    不会报错 能够编译成功 因为常量类对象 只能访问const成员函数
    //    cout << c.getConstCount() << endl;
    //    //2. 这行代码能否编译?为什么?如果不能,如何修改?
    //    会报错,因为常量类对象无法访问普通成员方法  ,如果想要访问该方法
    //    需要声明该方法时 加上const 关键字
    //    cout << c.getCount() << endl;  //
    //    return 0;
    //}
    #pragma endregion
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏