2.17 C++类与const关键字
参考: http://www.weixueyuan.net/view/6348.html
总结:
const成员变量的初始化只有唯一的一条途径:参数初始化表。
const成员函数可以使用类中的所有成员变量,但是不能修改变量的值。
而普通的成员函数不能访问常对象的成员变量,其它的成员变量都可以访问,普通的成员函数可以修改的成员变量也只有非const成员变量了。
一旦将对象定义为常对象之后,该对象就只能调用类中的常成员函数了。
要求修改常对象中的某个成员变量,这个时候如果是普通的成员变量是不能被修改的。为了满足这一需求,C++提供了mutable关键字。 常对象调用const成员函数修改该变量即可。
有时候为了在函数中避免对对象本身做出什么修改,在函数形参前加上const关键字。
在类中,有时候为了避免误操作而修改了一些人们不希望被修改的数据,此时就必须借助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是非常合适的。
例1:
- 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 对象名(实参名);
这两种定义方式都是可以的,我们一旦将对象定义为常对象之后,该对象就只能调用类中的常成员函数了。
例2:
- #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关键字。
例3:
- #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函数则没有问题,因为这些函数没有修改成员变量。
2.17 C++类与const关键字的更多相关文章
- C++学习11 类和new、delete操作符 类与const关键字
如果你是Java.C#.PHP程序员,那么会对 new 非常熟悉,在这些编程语言中,只能通过 new 来创建对象. 在C++中,你可以像定义变量一样来创建对象,如: Student stu; //对象 ...
- C++ —— 类中static和const关键字声明变量的初始化方式总结
在类中声明变量/常量时,经常会用到static.const关键字.对于该变/常量的初始化问题,网上有许多相关文章,但是大多不够完善,或者存在错误.经过实际验证,总结如下: (注明:测试编译平台为VS2 ...
- C++ 类中的const关键字
//类中的const关键字 #include<iostream> using namespace std; class Point{ public: //这个const关键字本质上修饰的是 ...
- PHP的final关键字、static关键字、const关键字
在PHP5中新增加了final关键字,它可以加载类或类中方法前.但不能使用final标识成员属性,虽然final有常量的意思,但在php中定义常量是使用define()函数来完成的. final关键字 ...
- C++中const关键字的使用总结
C++中使用const关键字来修饰常量,下面从两个方面总结:变量和成员函数. 变量:const可以修饰普通变量.指针(数组)和结构体. 1.const修饰普通变量是最简单的情形.这样的用法多为在程序中 ...
- 类中用const限定的成员函数
本文转自http://blog.csdn.net/whyglinux/article/details/602329 类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非 ...
- C++ 不能在类体外指定关键字static
C++ static 函数的问题 近日读 C++ primer 中static 一章 , 有这么一句话, “静态成员函数的声明除了在类体中的函数声明前加上关键字static 以及不能声明为const ...
- final关键字+const关键字
final关键字 1.如果我们希望某个类不被其它的类来继承(可能因为安全考虑),可以使用final. 例题 <? final class A{} class B extends A{};//会报 ...
- C++中的const关键字
http://blog.csdn.net/eric_jo/article/details/4138548 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方 ...
随机推荐
- Navicat Premium 12如何激活
Navicat Premium 12如何激活 一.总结 一句话总结:激活过程中一定要断开网络连接,点电脑的飞行模式没有用,断开网络连接之后才有手动激活的选项 需要断网 点电脑的飞行模式无用 二.Nav ...
- ico 图标 生成 工具 网站
http://www.faviconico.org/favicon favicon.ico在线制作,在线Favicon.ico制作转换工具
- 非常好的 gdb tui 的文章
http://beej.us/guide/bggdb/ Help Commands help command Get help on a certain command apropos keyword ...
- 雷林鹏分享: C# 简介
C# 简介 C# 是一个现代的.通用的.面向对象的编程语言,它是由微软(Microsoft)开发的,由 Ecma 和 ISO 核准认可的. C# 是由 Anders Hejlsberg 和他的团队在 ...
- 使用jquery.mobile和WebSQL实现记事本功能
1.记事本列表页 1.1.页面结构与样式: <div data-role="page" id="home"> <div data-role=& ...
- hadoop挂载多硬盘,ZZ-- multiple disks per node
hadoop挂载多硬盘 ...multiple disks per node multiple disks per node Read more at: http://www.queryhome.c ...
- android studio 中的快捷键汇总
1.Ctrl + B 跳入/跳出方法或者资源文件.将鼠标光标定位到某个方法或者资源id的调用处,按Ctrl + B,将会跳入该方法或者资源文件内部,功能等同于Ctrl + 鼠标左键.如果将鼠标光标定位 ...
- python3-----多进程、多线程、多协程
目前计算机程序一般会遇到两类I/O:硬盘I/O和网络I/O.我就针对网络I/O的场景分析下python3下进程.线程.协程效率的对比.进程采用multiprocessing.Pool进程池,线程是自己 ...
- php字段转义
addslashes() 函数返回在预定义的字符前添加反斜杠的字符串. 预定义字符是:在以下符号前加/ 单引号(') 双引号(") 反斜杠(\) NULL parse_str($str,$a ...
- pycharm安装步骤
python环境配置教程 https://jingyan.baidu.com/article/c45ad29c05c208051653e270.html 由于安装Pycharm时忘记截图了,所以详细安 ...