const 修饰成员函数 前后用法(effective c++ 03)
目录
const在函数后面
类的成员函数后面加 const,表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变。
const修饰成员函数的两个作用
在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 const,而对于改变数据成员的成员函数不能加 const。所以 const 关键字对成员函数的行为作了更加明确的限定:有 const 修饰的成员函数(指 const 放在函数参数表的后面,而不是在函数前面或者参数表内),只能读取数据成员,不能改变数据成员;没有 const 修饰的成员函数,对数据成员则是可读可写的。
除此之外,在类的成员函数后面加 const 还有什么好处呢?
“获得能力:可以操作常量对象”,其实应该是常量(即 const)对象可以调用 const 成员函数,而不能调用非const修饰的函数。
对于const成员函数,"不能修改类的数据成员,不能在函数中调用其他不是const的函数",这是由const的属性决定的 。
请看下面一个完整的例子,然后我再作一些说明。
#include <iostream>;
#include <string>;
using namespace std;
class Student {
public:
Student() {}
Student( const string& nm, int sc = 0 )
: name( nm ), score( sc ) {}
void set_student( const string& nm, int sc = 0 )
{
name = nm;
score = sc;
}
const string& get_name() const
{
return name;
}
int get_score() const
{
return score;
}
private:
string name;
int score;
};
// output student's name and score
void output_student( const Student& student )
{
cout << student.get_name() << "\t";
cout << student.get_score() << endl;
}
int main()
{
Student stu( "Wang", 85 );
output_student( stu );
}
设计了一个类 Student,数据成员有 name 和 score,有两个构造函数,有一个设置成员数据函数 set_student(),各有一个取得 name 和 score 的函数 get_name() 和 get_score()。请注意 get_name() 和 get_score() 后面都加了 const,而 set_student() 后面没有(也不能有const)。
const在函数前面
首先说一点题外话,为什么 get_name() 前面也加 const。如果没有前后两个 const 的话,get_name() 返回的是对私有数据成员 name 的引用,所以通过这个引用可以改变私有成员 name 的值,如
Student stu( "Wang", 85 );
stu.get_name() = "Li";
即把 name 由原来的 "Wang" 变成了 "Li",而这不是我们希望的发生的。所以在 get_name() 前面加 const 避免这种情况的发生。
那么,get_name() 和 get_score() 这两个后面应该加 const的成员函数,如果没有 const 修饰的话可不可以呢?回答是可以!但是这样做的代价是:const对象将不能再调用这两个非const成员函数了。如
const string& get_name(); // 这两个函数都应该设成 const 型
int get_score();
void output_student( const Student& student )
{
cout << student.get_name() << "\t"; // 如果 get_name() 和 get_score() 是非const成员函数,这一句和下一句调用是错误的
cout << student.get_score() << endl;
}
由于参数student表示的是一个对const Student型对象的引用,所以 student 不能调用非const成员函数如 set_student()。如果 get_name() 和 get_score() 成员函数也变成非const型,那么上面的 student.get_name() 和 student.get_score() 的使用就是非法的,这样就会给我们处理问题造成困难。
因此,我们没有理由反对使用const,该加const时就应该加上const,这样使成员函数除了非const的对象之外,const对象也能够调用它。
总结
1. const在函数后面表示函数不可以修改这个类的成员变量
2. const在函数前面用于描述返回值,表示返回一个常量
const 修饰成员函数 前后用法(effective c++ 03)的更多相关文章
- C++基础-4-封装(构造函数与析构函数,深拷贝与浅拷贝,静态成员,this,友元,const修饰成员函数)
4. 封装 4.1.1 封装的意义 1 #include<iostream> 2 #include<string> 3 using namespace std; 4 5 con ...
- 11. const 修饰成员函数
const 限定只读,对函数的实参进行保护 常数据成员:必须出现在类的定义体中,常数据成员必须进行初始化,并且不能被更新,但常数据成员的初始化只能通过构造函数的初始化列表进行 1. 常函数 成员函数加 ...
- const修饰虚函数
[1]程序1 #include <iostream> using namespace std; class Base { public: ; }; class Test : public ...
- .static 和const分别怎么用,类里面static和const可以同时修饰成员函数吗。
static的作用: 对变量: 1.局部变量: 在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量. 1)内存中的位置:静态存储区 2)初始化:局部的静态变量只能被初始化一次, ...
- Qt中利用QTime类来控制时间,这里简单介绍一下QTime的成员函数的用法:
Qt中利用QTime类来控制时间,这里简单介绍一下QTime的成员函数的用法: ------------------------------------------------------------ ...
- C++的const类成员函数
转自:http://blog.csdn.net/lihao21/article/details/8634876 我们知道,在C++中,若一个变量声明为const类型,则试图修改该变量的值的操作都被视编 ...
- C++ const修饰不同类型的用法
const取自constant的缩写,本意是不变的,不易改变的意思 一.修饰普通变量 const int a = 7; int b = a; //正确 a = 8; ...
- 【转】C++的const类成员函数
我们知道,在C++中,若一个变量声明为const类型,则试图修改该变量的值的操作都被视编译错误.例如, const char blank=' '; blank='\n'; //错误 面向对象程序设计中 ...
- C++中的const成员函数(函数声明后加const,或称常量成员函数)用法详解
http://blog.csdn.net/gmstart/article/details/7046140 在C++的类定义里面,可以看到类似下面的定义: 01 class List { 02 priv ...
随机推荐
- 剑指Offer的学习笔记(C#篇)-- 整数中1出现的次数(从1到n整数中1出现的次数)
题目描述 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1.10.11.12.13因此共出现6次,但是对于后面问题他就没辙了. ...
- 2016 CCPC-Final
A.The Third Cup is Free #include <bits/stdc++.h> using namespace std; typedef long long ll; in ...
- SQL Server插入中文乱码
如果数据库的Collocation是英文的,字段是varchar类型,向表中插入中文数据,会出现乱码. 解决方法: 方法1. 修改varchar 为 nvarchar类型, 并在插入数据前加N,例如: ...
- Luogu P1155 双栈排序 图论?模拟吧。。
今天想做做图论,于是点开了这道题....(是二分图染色然而我没看出来) 四种操作及条件: 1. s1.push() 需满足 待push的元素小于栈顶 && { 若在原序列中,待push ...
- 【bzoj1503】[NOI2004]郁闷的出纳员
1503: [NOI2004]郁闷的出纳员 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 13890 Solved: 5086[Submit][Stat ...
- net core 2.0 web api + Identity Server 4 + angular 5
net core 2.0 web api + Identity Server 4 + angular 5前台使用angular 5, 后台是asp.net core 2.0 web api + ide ...
- Middleware-请求管道的构成
Middleware-请求管道的构成 在 ASP.NET 中,我们知道,它有一个面向切面的请求管道,有19个主要的事件构成,能够让我们进行灵活的扩展.通常是在 web.config 中通过注册 Htt ...
- ES6:string.raw浅析
当前正学习ES6 ,遇到string.raw费心思,现将试验后的结果整理如下: 网上得来的试验: 语法 String.raw`templateStr`; String.raw(obj, ...subs ...
- ms sqlserver 清除数据库日志脚本
USE [master] GO ALTER DATABASE F360DW SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE F360DW SET ...
- 《java学习三》并发编程 -------线程池原理剖析
阻塞队列与非阻塞队 阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞.试图从空的阻塞队列中获取元素的线程将会被阻塞,直到 ...