【C++】const对象和const成员

如果我们在定义一个对象之后,不希望在后面对这个对象进行修改,那么我们可以把这个对象声明为const对象。
声明为const对象之后,这个对象的所有数据成员后面都不能被修改!

const对象

定义类对象时可以将其指定为const对象。定义后const对象不能再被修改。
const对象不能调用非const类型的成员函数。
有两种方法来定义一个const对象:
const 类名 对象名
类名 const 对象名
这两种方法是等价的。

如果一个对象被定义成const对象,那么它就不能调用这个类中的非const成员函数。
const对象调用的成员函数一定都得是const!

//const
const CTime time4(10);
CTime const time5;

如果你用const对象引用了这个类中的非const成员函数,就会报错:

错误  1   error C2662: “int CTime::getHour(void)”: 不能将“this”指针从“const CTime”转换为“CTime &”
e:\chenhaoxiang\20170603\test2\test2\mian.cpp   34  1   test2

其实就是告诉我们const对象不能引用非const成员函数
为什么要有这个规则:
因为在非const成员函数内部可能对对象进行修改,比如set函数
这个规则也就是强制用户不要对const成员进行错误的修改

const成员

1.const数据成员

也就是变量,比如实例中的m_hour,m_minute是普通数据成员

在类内部使用const关键字来声明const数据成员。const数据成员的值不能被修改。
初始化时比较特殊,只能通过初始化列表初始化。不能在构造函数里赋值。

2.初始化列表

初始化列表:
除了在构造函数中对数据成员进行初始化,C++还提供另外一种方法来对数据成员进行初始化
初始化列表并不是在构造函数内进行初始化
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。

const int num;

必须初始化,而且不能在构造函数中初始化!

CTime::CTime() : num(10){

    m_hour = 0;
    m_minute = 0;
    m_second = 0;
    m_nNum++;
    cout << m_nNum << endl;
}
CTime::CTime(int hour) : num(10){
    this->m_hour = hour;
    //(*this).m_hour = hour; //效果一样的
}

//复制构造函数
CTime::CTime(CTime& time) : num(10){
    m_hour = time.m_hour;
    m_minute = time.m_minute;
    m_second = time.m_second;
    //cout << "进入复制构造函数" << endl;
}

每一个构造函数都需要初始化这个const成员,而且复制构造函数也需要初始化num,因为复制构造函数也是一种构造函数!

3.const成员函数

const成员函数只能被const对象引用。const成员函数内可以引用const数据成员,也可以引用非const数据成员,但不能修改非const数据成员的值。但不能调用非const成员函数。

int getNum() const;

对于const函数的外部定义,也需要写const限定符

int CTime::getNum() const {
    return num;
}

const成员函数存在的意义在于它能被const常对象调用

CTime const time5;
    cout << time5.getNum() <<endl;

如果在const成员函数的定义中出现了任何修改对象成员数据的现象,都会在编译时被检查出来

如果我们是真的想在const成员函数中修改值呢,比如我需要m_age++;
比如下面定义了一个m_age 类成员:

int m_age;
int CTime::getNum() const {
    if (m_age == 0){
        m_age++;
    }
    else{
        m_age = 0;
    }
    return num;
}

假如我们不做其他事情,这样的写法,在编译时是无法通过的。

有些时候,我们想要让const函数具有修改某个成员数据值的能力。
比如一些内部的状态量,对外部用户无所谓,但是对整个对象的运行却大有用处,如支持缓存的技术。
遇到这种问题,我们可以把一个成员数据定义为mutable(多变的),它表示这个成员变量可以被const成员函数修改却不违法。
比如下面定义了这样一个m_age 类成员:

mutable int m_age;
int CTime::getNum() const {
    if (m_age == 0){
        m_age++;
    }
    else{
        m_age = 0;
    }
    return num;
}

这样,即使像getNum()这样的const成员函数修改它也是合法的。
但需要注意的时,不要滥用mutabe描述符,如果在某个类中只有少数一部分是被允许const常量函数修改的,使用mutable是再合适不过的。如果大部分数据都定义为mutable,那么最好将这些需要修改的数据放入另一个独立的对象里,并间接地访问它。

源代码下载地址:

GITHUB源码下载地址:点我进行下载

本文章由[谙忆]编写, 所有权利保留。
欢迎转载,分享是进步的源泉。

转载请注明出处:http://chenhaoxiang.cn

本文源自人生之旅_谙忆的博客

时间: 2024-10-14 16:27:17

【C++】const对象和const成员的相关文章

【C/C++学院】0820-Nullptr/const对象/类指针引用以及mallocfree与newde/类重载运算符/QT加法重载/类的重载赋值运算/自增在前在后差别/赋值重载深浅拷贝/重载下标

Nullptr #include<iostream> void go(int num) { std::cout << "gonum" << std::endl; } void go(void *p) { std::cout << "gop" << std::endl; } void main() { //void *p = nullptr; void *p = NULL;//C++是强类型,严格的类型检查

const对象,NULL和nullptr,C++中创建对象数组

 1.定义成了const之后的类 #include <iostream> class area { public: int x; int y; mutable int z; //不受const约束的类成员 area() :x(10), y(10), z(2) { } void printxy()const //不可以访问类中局部变量 { z = z + 1; std::cout << x << " " << y << &q

指针-请教一个顶层CONST和底层CONST的问题

问题描述 请教一个顶层CONST和底层CONST的问题 最近在看C++PRIMER这本书,对于书上所说的这个顶层和底层CONST的问题小弟不是很明白 所以特来这里想请教各位一下, CONST INT CI=42; CONST INT *P2=&CI;//允许改变P2的值,这是一个底层CONST 这句话不是很明白, 为什么能改变P2的值呢?P2不是一个指针常量吗?自身的值是不能 改变的呀,P2指向的对象CI的值也是不能改变的呀,所以等号前面是顶层CONST,后面 是底层CONST我 是这么理解的也

link中能不能不通过实例化对象访问一个成员函数?真的很焦急,谢谢

问题描述 link中能不能不通过实例化对象访问一个成员函数?真的很焦急,谢谢 link中能不能不通过实例化对象访问一个成员函数?真的很焦急,谢谢 解决方案 不可以.因为方法被允许访问成员变量,你都没有实例化怎么访问? 解决方案二: 当然可以访问实例的public方法

c++-文件的读写,会将类对象的数据成员写入文件中。能将文件中的信息读入类对象的对应属性中。

问题描述 文件的读写,会将类对象的数据成员写入文件中.能将文件中的信息读入类对象的对应属性中. 情况一:无get,set,无<< >>重载函数的情况下如何将类对象的各个数据成员写入某个文件中(提示:可以在print函数中写代码). 情况二:当程序包含get,set函数而无<< >>重载函数时,如何将类对象的数据成员写入文件中. 情况三:当程序包含<< >>重载函数时,如何将类对象的数据成员写入文件中. 解决方案 大神在哪里,求,求大神

const char*, char const*, char*const的区别

const char*, char const*, char*const的区别问题几乎是C++面试中每次都会有的题目. 这个知识易混点之前是看过了,今天做Linux上写GTK程序时又出现个Warning,发散一下又想到这个问题,于是翻起来重嚼一下. 事实上这个概念谁都有只是三种声明方式非常相似: Bjarne在他的The C++ Programming Language里面给出过一个助记的方法: 把一个声明从右向左读. char * const cp; // * 读成 pointer to //

c++ operator&amp;amp;lt;&amp;amp;lt;的参数的const与非const的区别

问题描述 c++ operator<<的参数的const与非const的区别 friend ostream& operator<<(ostream& os,mystring& str); friend ostream& operator<<(ostream& os,const mystring& str); 我遇到的问题是用1的写法调用cout<<str1+str2<<endl时会出错.而用2的写法

c++-为什么 const 和非 const 的汇编代码一样,const 的却能保证不被修改呢?

问题描述 为什么 const 和非 const 的汇编代码一样,const 的却能保证不被修改呢? <C++ Primer>第五版,中文版.145 页. const int i = 42;//int i = 42; cout << i << endl; const int *p = &i; *const_cast<int *>(p) = 0; cout << i << endl; const int i = 42; 与 int

int *p,cons int *p,int const *p,int * const p,const int * const p,int const * const p的区别

 加有const关键字的几种情况的辨析 const修饰的代码 含义(特点) 等价性 int *p = &num; 1.       可以读自己 2.       可以通过*p改自己 3.       可以通过p = &data来看别人 权限最大 cons int *p = &num; 1.const放在左边意味着指向的是常量,这个常量不可以修改, 2.p = &data; (地址可以修改) 3.*p = 30;(这个时候是错误的) 这两者等价(应用:查看别人的账户) i