• 【C++】class的设计与使用(三)mutable(可变)和const(不变)


    const

    class Triangular{
    public:
    
    	int length() const{return _length;}
    	int beg_pos() const{return _beg_pos;}
    	int elem(int pos) const;
    
    	bool next(int &val);
    	void next_reaset()
    	{
    		_next=_beg_pos-1;
    	}
    	static vector<int>_elems;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • const修饰符紧接在函数参数列表之后(告诉编译器:这个成员函数不会更改类对象的内容);
    • 编译器会检查每个声明为const的成员函数,检看看他们是否真的没有改变类对象的内容,如果改变,就会产生编译错误;
    • 在class主体以外定义的成员函数,如果它是一个const成员函数,那就必须同时在声明定义中指定const:
    int Triangular::elem(int pos) const
    {
    	return _elems[pos-1];
    }
    
    • 1
    • 2
    • 3
    • 4
    • 然而返回一个非const引用,引用(“指向”)标注着const的成员函数的函数体内的对象也会产生问题:将标const的成员函数的函数体内的对象开放了出去,允许程序在其他地方加以修改:
    class val_class{
    public:
    	val_class(const BigClass &v)
    		:_val(v){}
    		
    	//有问题
    	BigClass& val()const 
    	{
    		return _val;
    	}
    private:
    	BigClass _val;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    解决:
    提供两份定义:const版本和non-const版本

    class val_class{
    public:
    	const BigClass& val() const{return _val;}
    	BigClass& val() {return _val;}
    };
    
    //non-const的类对象会调用non-const的成员函数val()
    //const的类对象调用const版的成员函数val()
    void example(const BigClass *pbc, BigClass &rbc)
    {
    	pbc->val();//调用const版本的成员函数val()
    	rbc.val();//调用非const版本的成员函数val()
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    设计类时,必须鉴定类的const成员函数
    没有一个const引用类参数可以调用公开接口(public:)中的non-const成分(但目前很多编译器对此情况都只给警告)

    mutable

    int sum(const Triangular &trian)
    {
    	if(!trian.length())
    		return 0;
    	
    	int val,sum=0;
    	trian.next_reset();
    	while(trian.next(val))
    		sum+=val;
    
    	return sum;
    }
    //trian是个const类对象
    //但next_reset()函数和next()函数都会更改_next的值
    //需要关键字mutable:
    class Triangular{
    public:
    	bool next(int &val)const;
    	void next_reset()const
    	{
    		_next=beg_pos-1;
    	}
    	//...
    private:
    	mutable int _next;
    	int _beg_pos;
    	int _length;
    };
    //next_reset()函数和next()函数既可以修改_next的值
    //又可以被声明为const成员函数
    
    • 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
    • 29
    • 30

    关键字mutable:对数据成员所做的改变并不会破坏类对象的常量性

  • 相关阅读:
    Linux之shell语法
    数据结构之链表
    gitlab runner
    DDOS和CC攻击区别,哪种对服务器伤害大
    SpringBoot 开放HTTPS HTTP ,并且强制HTTP转HTTPS端口
    C++ 类模板实现栈和循环队列
    在表格开发中,如何选择适合自己的处理工具?
    Termius 8.4.0(多协议远程管理软件)
    ESP8266--SDK开发(延时、定时器)
    arm栈推导
  • 原文地址:https://blog.csdn.net/weixin_49347928/article/details/133280981