常类型:使用类型修饰符const说明的类型,常类型的变量或对象成员的值在程序运行期间是不可改变的。

3.10.1 常引用

如果在说明引用时用const修饰,则被说明的引用为常引用。如果用常引用做形参,便不会产生对实参
的不希望的更改。常引用的说明形式如下:

const 类型 &引用名;

例如:int a=5;
const int &b=a;
其中,b是一个常引用,它所引用的对象不允许更改。如果出现:b=12 //则是非法的

在实际应用中,常引用往往用来作形参,这样的参数称为长形参

  例 3.39  常引用作函数的参数
*/
#include<iostream>
using namespace std;
int add(const int &,const int &); //声明add的形参是常引用
int main()
{
int a=;
int b=;
cout<<a<<"+"<<b<<"="<<add(a,b)<<endl; a = ; //在add函数外,实参是可以改变的
b = ; //在add函数外,实参是可以改变的
cout<<a<<"+"<<b<<"="<<add(a,b)<<endl; return ;
}
int add(const int &i,const int &j) //常引用作函数形参
{
//i=i+20; //不允许改变i的值
return i+j;
} /*
程序运行结果: 20+30=50
15+50=65 说明:由于add函数两个形参都定义为常引用,所以在函数中不能改变i和j的值,如果改变它们的
值,编译将会出错,如本程序中执行的函数add加有注释的语句"i=i+20;",将会出现编译
错误。因此,用常引用作形参,能够避免对是实参的更改,保证了数据的安全性。
*/

3.10.2 常对象

如果说明对象时用常引用const修饰,则被说明的对象为常对象。常对象的数据成员值在
在对象的整个生存周期内不能被改变。常对象的说明形式如下:

类名 const &对象名[(参数表)]

或 const 类名 &对象名[(参数表)]

在定义对象时必须被初始化,而且不能被更新。

例 3.40   非常对象和常对象的比较
*/
#include<iostream>
using namespace std;
class Sample{
public:
Sample(int m,int n)
{
i = m;
j = n;
}
int j;
void setvalue(int x)
{
i = x;
}
void show()
{
cout<<"i="<<i<<endl;
cout<<"j="<<j<<endl;
}
private:
int i; };
int main()
{
Sample s(,); //对象s是普通对象,而不是常对象
s.setvalue();
s.j=;
s.show(); //运行结果是 i=30 j=40 /*
Sample const s(10,20); //对象s是常对象
s.setvalue(30); //运行错误,C++不允许间接的更改i的值
s.j=40; //运行错误,C++不允许置接的更改j的值
s.show(); //运行错误,C++不允许常对象调用普通的
*/ return ;
}

3.10.3 常对象成员

1. 常数据成员
类的数据成员可以是常量或常引用,使用const说明的数据成员称为常数据成员。如果在
一个类中说明了常数据成员,那么构造函数就只能通过成员初始化列表对该数据成员进行
初始化,而其他人任何函都不能对该成员赋值。

   例3.  常数据成员的使用
*/
#include<iostream>
using namespace std;
class Date{
public:
Date(int y,int m,int d);
void show();
private:
const int year; //常数据成员
const int month; //常数据成员
const int day; //常数据成员
};
Date::Date(int y,int m,int d):year(y),month(m),day(d){} //采用成员初始化列表,对数据成员进行初始化
void Date::show()
{
cout<<year<<".";
cout<<month<<".";
cout<<day<<endl;
}
int main()
{
Date date1(,,);
Date date2(,,);
date1.show();
date2.show();
return ;
} /*
运行结果为:2015.5.7
2015.5.8 该程序中定义了如下3个常数据成员:
const int year; //常数据成员
const int month; //常数据成员
const int day; //常数据成员 其中year、month、day是int类型的数据成员。需要注意到是构造函数的格式如下: Date::Date(int y,int m,int d):year(y),month(m),day(d){} 其中,冒号后面是一个成员初始化列表,它包含3个初始化项。这是由于year、month、
和day都是常数据成员,C++规定只能通过构造函数的初始化列表对常数据成员进行初始化。
在函数体中采用赋值语句对数据成员直接赋初值是非法的。如以下形式的构造函数是错误的: Date::Date(int y,int m,int d)
{
year = y; //非法
month = m; //非法
day = d; //非法
} 一旦对某对象的常数据成员初始化后,该数据成员的值是不能改变,但不同对象中的该数据成员
的值可以是不同的(在定义对象时给出) 如: Date date1(2015,5,7);
Date date2(2015,5,8);
*/

2、常成员函数

在类中使用关键字const说明的成员函数为常成员函数,常成员函数的说明格式如下:

类型说明符 函数名(参数表) const;

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

例3. 常成员函数的使用
*/
#include<iostream>
using namespace std;
class Date{
public:
Date(int y,int m,int d);
void show(); //声明普通的成员函数show()
void show() const; //声明常成员函数show()
private:
const int year; //常数据成员
const int month; //常数据成员
const int day; //常数据成员
/*
int year; //普通数据成员
int month; //普通数据成员
int day; //普通数据成员
*/
};
Date::Date(int y,int m,int d):year(y),month(m),day(d){} //定义构造函数,采用成员初始化列表,
//对数据成员进行初始化 void Date::show() //定义普通的成员函数show()
{
cout<<"Date::show1()"<<endl;
cout<<year<<".";
cout<<month<<".";
cout<<day<<endl;
}
void Date::show() const //定义常成员函数show()
{
cout<<"Date::show2()"<<endl;
cout<<year<<".";
cout<<month<<".";
cout<<day<<endl;
}
int main()
{
Date date1(,,); //定义普通对象date1
date1.show(); //调用普通的成员函数show const Date date2(,,); //定义常对象date2
date2.show(); //调用常成员函数show return ;
} /*
程序运行结果如下:
Date::show1()
2015.4.7
Date::show2()
2015.4.8 本程序中,类Date中说明了两个同名成员函数show,一个是普通成员函数,另一个是常成员函数,
它们是重载的。可见,关键字const可以被用于区分重载函数。

说明:

1、常成员函数可以访问常数据成员,也可以访问普通数据成员。常数据成员可以被常成员函数访问,
也可以被普通成员函数访问。

2、如果将一个对象说明为常对象,则通过该对象只能调用它的常成员函数,而不能调用普通的成员
函数。常成员函数是常对象唯一的的对外接口,这时C++从语法上对常对象的保护。

表3.2 常成员函数和普通成员函数的访问特性比较
--------------------------------------------------------------------------------------------------------------- 
数据成员 |                         普通成员函数 |                               常成员函数
--------------------------------------------------------------------------------------------------------------- 
普通数据成员                 可以访问,也可以改变值               可以访问,但不可以改变值

常数据成员                     可以访问,但不可以改变值           可以访问,但不可以改变值

常对象的数据成员         不允许访问和改变值                       可以访问,但不可以改变值

3、常成员函数不能更新对象的数据成员,也不能调用该类中的普通成员函数,这就保证了在常成员
函数中绝对不会更新数据成员的值。

C++:常类型Const的更多相关文章

  1. C++ 常量类型 const 详解

    1.什么是const? 常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的.(当然,我们可以偷梁换柱进行更新:) 2.为什么引入const? const 推出的初始目的 ...

  2. ERROR C3848:具有类型"const XXX" 的表达式会丢失一些 const-volatile 限定符以调用"YYY" with"ZZZ"

    今天看书,Thinking in c++ volume 2 "Adaptable function objects" 里面作者说: Suppose, for example, th ...

  3. C++ Const(常类型)的作用总结

    C++ Const的作用总结 面试或者工作中,我们经常遇到const修饰符定义的变量,函数和对象等.那么const的作用具体是什么,有哪些.今天自己好好的总结了一下,记录下来方便自己以后时间久了不记得 ...

  4. 类的常成员const

    成员数据 以Human为例: 类中: 传统的初始化方式:                                                                        ...

  5. 3.GDScript(1)概览

    GDScript 是上面提到的用于Godot的主要语言.和其他语言相比,它与Godot高度整合,有许多优点: 简单,优雅,设计上为Lua.Python.Squirrel等语言用户所熟悉. 加载和编译速 ...

  6. define宏定义和const常变量区别

    1.define是宏定义,程序在预处理阶段将用define定义的内容进行了替换.因此程序运行时,常量表中并没有用define定义的常量,系统不为它分配内存.const定义的常量,在程序运行时在常量表中 ...

  7. const 常引用

    常类型是指使用类型修饰符 const 说明的类型,常类型的变量或对象的值是不能被更新的. 这篇主要说常引用.常引用是指所引用的对象不能被更新. 在实际应用中,常引用往往用来作为函数的形参,这样的参数称 ...

  8. const类型总结

    const 表示常类型   作用: 1.具有不可变性.   2.可以很方便对参数进行调整和修改,和宏定义一样,不变则已,变都变.   3.保护被修饰的东西,防止被意外修改.(如:在修饰函数的形参时,加 ...

  9. C++ const 常量和常指针

    常量,该指针所指向的值为只读 ; const int * p = &a; 常指针,该指针的值为只读,不可再指向其他地址 const * const p = &a; 常值,常指针 con ...

随机推荐

  1. verilog逻辑复制

    本文转自:http://www.cnblogs.com/linjie-swust/archive/2012/03/27/FPGA_verilog.html 在FPGA设计中经常使用到逻辑复制,逻辑复制 ...

  2. [原]项目进阶 之 持续构建环境搭建(二)Nexus私服器

    上一篇博文项目进阶 之 持续构建环境搭建(一)架构中,我们大致讲解了一下本系列所搭建环境的基本框架,这次开始我们进入真正的环境搭建实战.重点不在于搭建的环境是否成功和完善,而是在搭建过程中充分认识到每 ...

  3. fawef

    欢迎使用马克飞象 @(示例笔记本)[马克飞象|帮助|Markdown] 马克飞象是一款专为印象笔记(Evernote)打造的Markdown编辑器,通过精心的设计与技术实现,配合印象笔记强大的存储和同 ...

  4. C# Winform 拖放操作

    http://www.cnblogs.com/imlions/p/3189773.html 在开发程序的时候,为了提高用户的使用体验,或满足相关用户的功能,总是离不开拖放功能.而本文是总结winfor ...

  5. Eclipse中的Web项目自动部署到Tomcat(转)

    转自:http://www.cnblogs.com/ywl925/p/3815173.html 问题: 这里就有个问题,是怎么把Eclipse中的网站项目自动部署到tomcat中.在Eclipse中做 ...

  6. Win7超级终端查看单片机printf输出

    问题描述:     编写单片机C程序时,经常会用到printf输出信息进行查看,如何查看printf输出? 问题解决:     (1)编写单片机C程序     ucos是一个实时多任务操作系统,以上是 ...

  7. mvc 分页js

    <script type="text/javascript">     var configA = {         options: {             m ...

  8. POJ 3553 Task schedule

    原题链接:http://poj.org/problem?id=3553 这道题主要就是贪心思想吧,对于每个job,根据其截止时间 dj 从小到大排序,我们必须要尽快把dj最小的job完成掉,这样才能使 ...

  9. 【BZOJ】【1877】【SDOI2009】晨跑

    网络流/费用流 费用流入门题……根本就是模板题好吗! 拆点搞定度数限制,也就是每个点最多经过一次……源点汇点除外. /***************************************** ...

  10. jquery-validation 学习总结

    一.用前必备 项目主页:http://bassistance.de/jquery-plugins/jquery-plugin-validation/ API: http://jquery.bassis ...