C++中的常对象与常对象成员详解

常对象

常对象必须在定义对象时就指定对象为常对象。

常对象中的数据成员为常变量且必须要有初始值,如


代码如下:

Time const t1(12,34,36); //定义t1为常对象

这样的话,在所有的场合中,对象t1中的所有数据成员的值都不能被修改。凡希望保证数据成员不被改变的对象,可以声明为常对象。

定义常对象的一般形式为

类名    const    对象名(实参列表);

也可以把const写在最左面

const    类名    对象名(实参列表);

二者等价

如果一个对象被声明为常对象,则不能调用该对象的非const型的成员函数(除了由系统自动调用的隐式构造函数和析构函数)。

否则就会报错

这样做是为了方式非const型的成员函数修改常对象中的数据成员的值,因为const型的成员函数是不可以修改对象中的数据成员的值的(这个后面还会说到)。

那么,怎样才能引用常变量中的数据成员呢?很简单,我们只需要将该成员函数声明称const型的成员函数(常成员函数)即可。


代码如下:

void Print() const;

常成员函数可以访问常对象中的数据成员,但仍然不允许修改常对象中数据成员的值。

有时在编程时有要求,一定要修改常对象成员中的某个数据成员的值(例如类中有一个用于计数的变量count,其值应当不能变化),

对该数据成员声明为mutable,如


代码如下:

mutable int count;//定义一个在常对象中可以被改变的数据成员

把count声明为可变的数据成员,这样就可以用声明为const的成员函数来修改它的值。

=========================一个简单的示例程序1.1====================================


代码如下:

#include<iostream>
using namespace std;
class Student
{
<span style="white-space:pre"> </span>public:
<span style="white-space:pre">  </span>Student(int n,float s):num(n),score(s){}
<span style="white-space:pre">  </span>void change(int n,float s) const{num=n;score=s;}
<span style="white-space:pre">  </span>void display() const{cout<<num<<"\t"<<score<<endl;}
<span style="white-space:pre"> </span>private:
<span style="white-space:pre">  </span>mutable int num;
<span style="white-space:pre">  </span>mutable float score;
} ;
int main()
{
<span style="white-space:pre"> </span>Student const stud(101,78.5);
<span style="white-space:pre"> </span>stud.display();
<span style="white-space:pre"> </span>stud.change(101,80.5);
<span style="white-space:pre"> </span>stud.display();
<span style="white-space:pre"> </span>return 0;
};

我们定义了常对象stud,然后分别调用了两个常函数display()和change(),但是在change函数中要修改常对象中的num和score的值,所以我们将num和score定义为mutable.
常对象成员

1.常数据成员
其作用和用法与一般常变量相似,用关键字const来声明常数据成员。常数据成员的值是不能改变的。
只能通过构造函数的参数初始化表对常数据成员进行初始化。

在类体中声明常数据成员


代码如下:

const int num;//声明hour为常数据成员

在类外定义构造函数


代码如下:

Student::Student(int n,float s):num(n),score(s){} //通过参数初始化表对常数据成员num和score初始化

在类体中声明了某一个数据成员为常数据成员后,该类所有对象中的该数据成员的值都是不能改变的,但不同对象中该变量成员的值可以是不同的(分别在初始化时指定)。

2.常成员函数

如果将成员函数声明为常成员函数,则只能引用本类中的数据成员,而不能修改它们。
注意:常对象只能引用常成员函数

常成员函数的定义形式:


代码如下:

void Print() const;//注意const的位置在函数名和括号之后

const是函数类型的一部分,在声明函数和定义函数都要有const关键字,在调用时不必加const。

常成员函数可以const数据成员,也可以引用非const数据成员,但是都不能修改他们;

不是常成员函数的函数可以调用const数据成员,但是不能修改它们,也可以调用非const数据成员,并且可以修改它们。

具体情况,如图1:

还要注意一下三点:
1.不要误认为常对象中的成员函数都是常成员函数,常对象只保证其所有数据成员的值不被修改。

2.如果在常对象中的成员函数未加const声明,则编译系统会把它当最非const成员函数处理。

3.还要注意,常成员函数不能调用另外一个非cosnt成员函数。

(0)

相关推荐

  • 深入理解c++常成员函数和常对象

    先明确几个概念: 1. 常对象只能调用常成员函数. 2. 普通对象可以调用全部成员函数. 3. 当对一个对象调用成员函数时,编译程序先将对象的地址赋给this指针,然后调用成员函数,每次成员函数存取数据成员时,由隐含使用this指针. 4. 当一个成员函数被调用时,自动向它传递一个隐含的参数,该参数是一个指向这个成员函数所在的对象的指针. 5. 在C++中,this指针被隐含地声明为: X *const this,这意味着不能给this 指针赋值: 在X类的const成员函数中,this指针的类

  • C++常对象精讲_const关键字的用法

    const关键字: 用const修饰的定义对象称为常对象: 用const修饰的声明成员函数称为常成员函数: 用const修饰的声明数据成员称为常数据成员. 变量或对象被 const修饰后其值不能被更新.因此被const修饰的变量或对象必须要进行初始化. 常对象说明:常对象是指对象的数据成员的值在对象被调用时不能被改变.常对象必须进行初始化,且不能被更新.不能通过常对象调用普通成员函数,但是可以通过普通对象调用常成员函数.常对象只能调用常成员函数.常对象的声明如下: const       <类名

  • 详解C++中的this指针与常对象

    C++ this指针详解 this 是C++中的一个关键字,也是一个常量指针,指向当前对象(具体说是当前对象的首地址).通过 this,可以访问当前对象的成员变量和成员函数. 所谓当前对象,就是正在使用的对象,例如对于stu.say();,stu 就是当前对象,系统正在访问 stu 的成员函数 say(). 假设 this 指向 stu 对象,那么下面的语句中,this 就和 pStu 的值相同: Student stu; //通过Student类来创建对象 Student *pStu = &s

  • 浅析成员函数和常成员函数的调用

    在Coordinate类中,有一个Display()成员函数和一个Display() const常成员函数,代码如下 class Coordinate{ public: Coordinate(int x,int y); void Display() const; void Display(); private: int m_iX; int m_iY; }; #include <iostream> #include "Coordinate.h" using namespace

  • C++中指向对象的常指针与指向常对象的指针详解

    指向对象的常指针 将指向对象的指针变量声明为const型,并使之初始化,这样指针值始终保持为其初始值,不能改变. 复制代码 代码如下: Time t1(10,12,15),t2;Time * const ptr1=&t1;ptr1=&t2; 定义指向对象的常指针的一般形式为 类名    *    const    指针变量=对象地址; 注意应该在定义指针变量时使之初始化 指向对象的常指针变量的值不能被改变,即始终指向同一个对象,但可以改变其所指向对象中的数据成员(非const型)的值. 往

  • js基础之DOM中document对象的常用属性方法详解

    -----引入 每个载入浏览器的 HTML 文档都会成为 Document 对象. Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问. 属性 1  document.anchors  返回对文档中所有 Anchor 对象的引用.还有document.links/document.forms/document.images等 2  document.URL       返回当前文档的url 3  document.title       返回当前文档的标题 4  do

  • 基于js对象,操作属性、方法详解

    一,概述 在Java语言中,我们可以定义自己的类,并根据这些类创建对象来使用,在Javascript中,我们也可以定义自己的类,例如定义User类.Hashtable类等等. 目前在Javascript中,已经存在一些标准的类,例如Date.Array.RegExp.String.Math.Number等等,这为我们编程提供了许多方便.但对于复杂的客户端程序而言,这些还远远不够. 与Java不同,Java2提供给我们的标准类很多,基本上满足了我们的编程需求,但是Javascript提供的标准类很

  • Python对象类型及其运算方法(详解)

    基本要点: 程序中储存的所有数据都是对象(可变对象:值可以修改 不可变对象:值不可修改) 每个对象都有一个身份.一个类型.一个值 例: >>> a1 = 'abc' >>> type(a1) str 创建一个字符串对象,其身份是指向它在内存中所处的指针(在内存中的位置) a1就是引用这个具体位置的名称 使用type()函数查看其类型 其值就是'abc' 自定义类型使用class 对象的类型用于描述对象的内部表示及其支持的方法和操作 创建特定类型的对象,也将该对象称为该类

  • javascript设计模式之对象工厂函数与构造函数详解

    下面通过文字详解加代码分析的方式给大家分享下javascript设计模式之对象工厂函数与构造函数的相关知识. 概述使用对象字面量,或者向空对象中动态地添加新成员,是最简单易用的对象创建方法.然而,除了这两种常用的对象创建方式,JavaScript还提供了其他方法创建对象.1).使用工厂函数创建对象我们可以编写一个函数,此函数的功能就是创建对象,可将其. 概述 使用对象字面量,或者向空对象中动态地添加新成员,是最简单易用的对象创建方法. 然而,除了这两种常用的对象创建方式,JavaScript还提

  • Vue路由对象属性 .meta $route.matched详解

    $route.fullPath 1 路由是:/path/:type真正路径是:/path/list 2 path匹配路径: /path/list 3 fullPath匹配路由: /path/:type 路由元信息 .meta const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, children: [ { path: 'bar', component: Bar, // a meta field meta:

  • Python对象的属性访问过程详解

    只想回答一个问题: 当编译器要读取obj.field时, 发生了什么? 看似简单的属性访问, 其过程还蛮曲折的. 总共有以下几个step: 1. 如果obj 本身(一个instance )有这个属性, 返回. 如果没有, 执行 step 2 2. 如果obj 的class 有这个属性, 返回. 如果没有, 执行step 3. 3. 如果在obj class 的父类有这个属性, 返回. 如果没有, 继续执行3, 直到访问完所有的父类. 如果还是没有, 执行step 4. 4. 执行obj.__ge

  • js对象的读取速度实例详解

    1.访问字面量和局部变量最快,而访问数组元素和对象成员相对较慢.访问对象成员时,就像作用域链一样,在原型链上搜索. 2.如果找到的成员在原型链中的位置太深,访问速度就会变慢. 所以要尽量减少对象成员的搜索次数和嵌套深度. 实例 // 进行两次对象成员查找 function hasEitherClass(element, className1, className2) { return element.className === className1 || element.className ==

  • Javascript对象及Proxy工作原理详解

    正文 这一章其实算是javascript的科普文章,其实这本书的读者一般都不会是入门者,因此按道理说应该不需要再科普才对.但是作者依旧安排了这一章,证明就是这一章内容与我们以为的对象不一样. Javascript中一切皆对象 这一句话大家应该耳熟能详,对于常规的字面量对象,和new出来的对象,大家应该都能分辨 const str = '' const str2 = new String() const obj = {} const obj2 = Object.create() 但是根据ECMA,

  • TypeScript数组实现栈与对象实现栈的区别详解

    目录 前言 数组实现栈 实现思路 实现代码 编写测试代码 对象实现栈 实现代码 编写测试代码 二者的区别 十进制转二进制 前言 栈作为一种数据结构,它可以应用在很多地方,当你需要经常获取刚存放进去的数据时,那么栈这种数据结构将是你的首选. 栈的实现方式一般有两种:数组实现和对象实现,这两种实现方式最终实现的功能都是一样的,但是在性能上却有着很大的差别. 本文将详细讲解这两种实现方式的差异并用TypeScript将其实现,欢迎各位感兴趣的开发者阅读本文. 数组实现栈 本文讲解的是栈用代码的实现,如

  • Java 用反射设置对象的属性值实例详解

    Java 用反射设置对象的属性值实例详解 /** * 用反射设置对象的属性值 * @param obj 需要設置值的對象 * @param fieldName 需要設置值的屬性 * @param value 需要设置的值 * @return 设置值后的对象 */ private Object invoke(Object obj, String fieldName, Object value) { String firstWord = fieldName.substring(0, 1).toUpp

随机推荐