在类中,有时候为了避免误操作而修改了一些人们不希望被修改的数据,此时就必须借助const关键字加以限定了。借助const关键字可以定义const类型的成员变量、成员函数、常对象以及对象的常引用。

const成员变量

const成员变量其用法和普通的const变量用法相似,在定义时只需在前面加上const关键字即可。const成员变量的初始化只有唯一的一条途径:参数初始化表。这个在前面已经提到过,不记得的话可以再去翻看参数初始化表那一小节。

const成员函数

const成员函数可以使用类中的所有成员变量,但是不能修改变量的值,这种措施主要还是为了保护数据而设置的。

我们来看一下下面的例子,例1依然是前面见过多次的book类,不过已经将与const成员函数不相关的代码都去掉了。在类中定义了两个构造函数及四个普通的成员函数,其功能分别是设置成员变量和获得成员变量。但这个book类与前面不相同的是在getprice函数和gettitle函数声明后面多了const关键字,这就是const成员函数,也可以成为常成员函数。常成员函数就是在声明和定义的时候在函数头部的结尾加上const关键字。注意在定义函数的时候const关键字依然是不能少的,具体可以参见例1中getprice和gettitle函数的定义。

为什么要将这两个函数定义成常成员函数呢?这两个函数的功能我们知道就是为了返回price和title的,功能单一,并且不希望修改这两个变量的,如此,定义成常成员函数是非常保险的一种做法,可以避免在这两个函数内部修改成员变量。如果需要修改这两个变量则只需通过setprice和settitle函数完成,因此设置为const是非常合适的。

    class book
{
public:
book(){}
book(char* a, double p = 5.0);
void setprice(double a);
void settitle(char* a);
double getprice()const;
char * gettitle()const;
private:
double price;
char * title;
};
double book::getprice()const
{
return price;
}
char * book::gettitle()const
{
return title;
}

常成员函数可以访问类中的任何成员变量,但是不能修改任何成员变量。而普通的成员函数不能访问常对象的成员变量,其它的成员变量都可以访问,普通的成员函数可以修改的成员变量也只有非const成员变量了,一旦加上了const关键字加以修饰,初始化完成后就不能被修改了。还有一点需要注意的是const成员函数是不能调用类中非const成员函数的。

const对象

const对象定义的基本语法如下:
    const 类名 对象名(实参名);
    类名 const 对象名(实参名);
这两种定义方式都是可以的,我们一旦将对象定义为常对象之后,该对象就只能调用类中的常成员函数了。

#include<iostream>
using namespace std; class book
{
public:
book(){}
book(book &b);
book(char* a, double p = 5.0);
void setprice(double a);
double getprice()const;
void settitle(char* a);
char * gettitle()const;
void display()const;
private:
double price;
char * title;
}; book::book(book &b)
{
price = b.price;
title = b.title;
} book::book(char* a, double p)
{
title = a;
price = p;
} void book::display()const
{
cout<<"The price of "<<title<<" is $"<<price<<endl;
} void book::setprice(double a)
{
price = a;
} double book::getprice()const
{
return price;
} void book::settitle(char* a)
{
title = a;
} char * book::gettitle()const
{
return title;
} int main()
{
const book Alice("Alice in Wonderland",29.9);
Alice.display();
// Alice.setprice(51.0);//compile error
return ;
}

在本例中,我们将类中的getprice、gettitle和display三个函数都声明为了常成员函数,之后在主函数中我们定义了一个常对象Alice,Alice作为一个常对象,只能调用常成员函数,因此在调用display函数时没有问题,但是在调用setprice函数时编译报错,因为setprice不是常成员函数。

有些时候我们在程序设计过程中要求修改常对象中的某个成员变量,这个时候如果是普通的成员变量是不能被修改的。为了满足这一需求,C++提供了mutable关键字。

    mutable int var;

通过这样的声明将变量var声明为可变的成员变量,此时如果要修改常对象的该变量时,只需要通过常对象调用const成员函数修改该变量即可。

对象的const引用

在将对象作为函数参数的时候,通常我们会采用引用的方式作为函数参数。有时候为了在函数中避免对对象本身做出什么修改,在函数形参前加上const关键字。

#include<iostream>
using namespace std; class book
{
public:
book(){}
book(book &b);
book(char* a, double p = 5.0);
void setprice(double a);
double getprice()const;
void settitle(char* a);
char * gettitle()const;
private:
double price;
char * title;
}; book::book(book &b)
{
price = b.price;
title = b.title;
} book::book(char* a, double p)
{
title = a;
price = p;
} void book::setprice(double a)
{
price = a;
} double book::getprice()const
{
return price;
} void book::settitle(char* a)
{
title = a;
} char * book::gettitle()const
{
return title;
} void display(const book &b)
{
b.setprice(59.9); //compile error
cout<<"The price of "<<b.gettitle()<<" is $"<<b.getprice()<<endl; //ok
} int main()
{
book Alice("Alice in Wonderland",29.9);
display(Alice);
book Harry("Harry potter", 49.9);
display(Harry);
return ;
}

在本例中,我们将display函数声明为顶层函数,其函数形参为book类对象的常引用,在函数内部我们首先调用public属性的setprice函数,企图修改price成员变量,编译无法通过。而在其后调用gettitle和getprice函数则没有问题,因为这些函数没有修改成员变量。

C++ 之const的使用的更多相关文章

  1. openssl 1.1.1 reference

    openssl 1.1.1 include/openssl aes.h: # define HEADER_AES_H aes.h: # define AES_ENCRYPT 1 aes.h: # de ...

  2. const,static,extern 简介

    const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...

  3. C++中的const

    一,C++中const的基本知识 1.C++中const的基本概念 1.const是定义常量的关键字,表示只读,不可以修改. 2.const在定义常量的时候必须要初始化,否则报错,因为常量无法修改,只 ...

  4. const extern static 终极指南

    const extern static 终极指南 不管是从事哪种语言的开发工作,const extern static 这三个关键字的用法和原理都是我们必须明白的.本文将对此做出非常详细的讲解. co ...

  5. const let,console.log('a',a)跟console.log('a'+a)的区别

    const 创建一个只读的常量 let块级作用域 const let重复赋值都会报错 console.log('a',a) a console.log('a'+a) a2 逗号的值会有空格:用加号的值 ...

  6. es6之let和const

    在javascript中,我们都知道使用var来声明变量.javascript是函数级作用域,函数内可以访问函数外的变量,函数外不能访问函数内的变量. 函数级作用域会导致一些问题就是某些代码块内的变量 ...

  7. construction const parameter问题 构造函数const引用参数问题

    工程在window下编译没有任何问题, 但是在linux(CentOS6)下编译就老是报错 C++ 编译器已升级到最新版 6.1.0 错误如下: In file included /bits/stl_ ...

  8. Error:const char* 类型的实参和LPCWSTR类型的形参不兼容的解决方法。

    在C++的Windows 应用程序中经常碰到这种情况. 解决方法: 加入如下转换函数: LPCWSTR stringToLPCWSTR(std::string orig) { size_t origs ...

  9. C#基础知识七之const和readonly关键字

    前言 不知道大家对const和readonly关键字两者的区别了解多少,如果你也不是很清楚的话,那就一起来探讨吧!探讨之前我们先来了解静态常量和动态常量. 静态常量 所谓静态常量就是在编译期间会对变量 ...

  10. const 与 readonly知多少

    原文地址: http://www.cnblogs.com/royenhome/archive/2010/05/22/1741592.html 尽管你写了很多年的C#的代码,但是可能当别人问到你cons ...

随机推荐

  1. @NotNull、@NotEmpty、@NotBlank的区别

    Spring中@NotNull.@NotEmpty.@NotBlank的区别@NotNull:用于基本数据类型@NotEmpty:用于集合类@NotBlank:用于String上面

  2. Chrome Extension 实战

    想起个问题,线上项目js要有bug,怎么进行调试修改. ------------- 想起来,方法应该是,拦截线上的js的请求,转到本地代码上进行调试... ------------- 网上看到 Chr ...

  3. 【CLR Via C#】2 程序集

    1 定义: 程序集是net 应用程序的部署单元,是组件服用,以及实施安全策略和版本策略的最小单元. 程序集是包含一个或者多个类型定义文件和资源的集合 本地dll或exe与程序集不同           ...

  4. 接口自动化 基于python实现的http+json协议接口自动化测试框架源码(实用改进版)

    基于python实现的http+json协议接口自动化测试框架(实用改进版)   by:授客 QQ:1033553122 欢迎加入软件性能测试交流QQ群:7156436     目录 1.      ...

  5. jQuery获取json数据

    出自---小瓶子编辑 $.each()方法接受两个参数,第一个是需要遍历的对象集合(JSON对象集合),第二个是用来遍历的方法,这个方法又接受两个参数,第一个是遍历的index,第二个是当前遍历的值. ...

  6. url override and HttpSession implements session for real

    无论cookie有没有禁用,HttpSession都有效 package com.test; import javax.servlet.ServletException; import javax.s ...

  7. 【Redis】Redis学习(七) Redis 持久化之RDB和AOF

    Redis 持久化提供了多种不同级别的持久化方式:一种是RDB,另一种是AOF. RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot). AOF ...

  8. Django Forms实例

    # Django的Form主要具有一下几大功能: # # 生成HTML标签 # 验证用户数据(显示错误信息) # HTML Form提交保留上次提交数据 # 初始化页面显示内容 # forms组件生成 ...

  9. gitlab查看项目ID/projectId

    背景 最近有个CI打包平台,项目projectId弄错,导致拉取到错误仓库.笔者一直通过项目名称(project name)访问,首次接触project id,搜索一圈才找到快捷查看方法,记录于此. ...

  10. SQL Server 中为何拥有db_owner权限的账号删除不掉数据库

    今天在公司的SQL Server服务器上,使用了一个只有public和dbcreator角色的账号"user1"在SMSS中去删除一个数据库,但是死活报错说没有权限,报错如下: D ...