C++ 我想这样用(七)
话接前篇,继续基于对象编程语法的剩余部分:
6.类的const成员函数和const对象
const数据成员:跟const常量一样,只是一个在类里(而且是在构造函数里),一个在类外而已,都必须初始化。
const成员函数:即普通成员函数后再加const。它可以读取数据成员的值,但不能修改它们。若要修改时,数据成员前必须加mutable。以指定其可被任意更改。mutable是ansi
c++考虑到实际编程时,可能一定要修改const对象中的某个数据成员而设的。const成员函数可以被相同参数表的非const成员函数重载。
const对象:仅能调用const成员函数,但是构造函数和析构函数是唯一不是const成员函数却可以被const对象调用的成员函数。
如下一个简单的例子
#include <iostream>
using namespace std;
class Aclass
{
public:
Aclass(int a,int b);
void Print() const;
void Print(); //重载const函数
void Set(int a);
protected:
private:
const int x;
mutable int y;
};
Aclass::Aclass(int a,int b):x(a),y(b)
{ }
void Aclass::Print() const
{
y = 9;
cout<<"x="<<
x <<"
y="<< y
<<endl;
}
void
Aclass::Print()
//实现,非const对象调用该函数而不是const函数
{
y = 8;
cout<<"x="<<
x <<"
y="<< y
<<endl;
}
void Aclass::Set(int a)
{
y = a;
}
int main()
{
Aclass a(1,2);
a.Print(); //x=1 y=8
const Aclass b(1,2);
b.Print(); //x=1 y=9
return 0;
}
*7.运算符重载
运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。也就是说,运算符重载是通过定义函数实现的。运算符重载实质上是函数的重载。重载运算符的函数一般格式如下:
函数类型 operator 运算符名称 (形参表列){对运算符的重载处理}
例如,想将“+”用于Complex(复数)的加法运算,函数的原型可以是这样的:
Complex operator + (Complex & c1,Complex &c2);
其中,operator是关键字,时候专门用于定义重载运算符的函数的,运算符名称就是C++提供给用户的预定运算符。注意:函数名是由operator和运算符组成。上面的operator+就是函数名,意思是“对运算符+重载“。只要掌握这点,这可以发现,这类函数和其他函数在形式上没有什么区别。
此外运算符的重载可以用两种方式实现,成员函数实现和友元函数实现运算符重载比较:
1.成员函数和友元函数实现运算符重载时,其函数名都必须以关键字operator开始,后面跟合适的运算符,但参数个数友元函数实现比成员函数实现时多了一个;
2.成员函数实现时,第一操作数必须是类的对象,但友元函数实现时,只要其中一个操作数是类的对象,所以通过友元函数实现时,两个操作数可以交换,满足交换率
3.有些运算符只允许成员函数实现(如赋值运算符),有些只允许友元函数实现(如提取、插入运算符)等;
4.成员函数隐含this指针,而友元函数没有this指针;
具体的实现方式不详说,因为操作符重载是基于对象编程里面少用的一个东西,不要花太多时间来研究。运算符重载与多态性是密切相关的,而这些都是面向对象的核心。这里我们说的是基于对象,是ADT。
*8.其他的
恩,其实和类有关的概念不止上面这些的,比如:
A。除了public和private之外的protect修饰符,我没有讲到,原因很简单,保护类型是用于继承关系的,我们的基于对象中的类都是无继承的;
B。友元的概念,也很复杂,如果你的基于对象风格的代码中会需要友元,那么一般只有两种情况:一是你的类太多太多了,类型杂乱,区分度不大,这时候你已经需要面向对象的编程风格了,你要考虑继承关系了,不能在单单使用扁平化类了。第二种情况就是,你的类很少却需要用友元,那么重新设计你的类型吧,因为你之前的设计一定是不合理的。
C。恩,还有复杂的运算符重载,其实运算符重载本身就有很多面向对象的思想在里面,因此基于对象的风格里面会很少使用,最多就那么几个简单的一元操作符重载而已。
【 A Better C = C with Class = C + new/delete + 参数默认值 + 函数重载 + 少量运算符重载 + 无继承class 】
这是本系列的最后一篇了,作为收尾,我引入两个描述:
描述一:C++有四个主流部分:better C,ADT,OO,和GP,以及发展中的functional, generative,meta programming等。Better C, 只增加函数重载、引用类型、缺省参数等简单特性的类C子集。ADT C++,整个程序由平面化的具体类(concrete class)对象构成,无继承,无多态。
描述二:“C++ 三人谈”中看到恶魔曾经指出C++ 的编程范式可以分为ADT+PP,GP,OO三个方向。1、ADT+PP ADT:abstract data type; 抽象数据类型 PP:procedure programme; 面向过程的编程范式 ADT+PP 就是说面向过程的编程范式+抽象数据类型,你可以理解为c++的前身:带类的C。2、(Generic Programming,泛型编程)号称编程思想的又一次革命。是一种基于参数化(parameterization)的编程技巧,目的是将有用的算法或者数据结构尽可能地一般化,并使其最优化。3、OO:面向对象的编程。
以上思想和Essentia C++书上的思想基本一致,也就说明了一个问题:C++是一种多范式的编程语言,不同的程序员用他写出不同范式的程序,没有优劣高下之别。本系列就是上述编程范式中的第一种,你可以把他叫做C with Class也可以叫做C+ADT还可以叫做基于对象,反正意思都是一个。基本的语法组成就是:面向过程语法(就是C语法)+扁平类语法(即只有抽象和封装,没有继承和多态)。
题外话:其实用单纯的C一样可以做到基于对象,而且丝毫没有什么痛感,但是如果你就是喜欢class关键字和“.”操作符带来的快感,那么本“C++ 我想这样用”系列描述的C with Class是你不错的选择。此外,有很多大牛甚至用C实现了泛型,单继承,多态。。。。但是我真心不推荐你使用,一来太另类,没有人力物力支持,二来毕竟是模拟实现的,不仅功能有限,那种蛋疼的感觉也不是一般人能习惯的。选择一门为该范式而生的语言是正统的选择,比如骨子里就是OO的Ruby,天生就是PP的C等等。
未来寄语:最近真的是发疯似的迷上了编程范式,这个系列算是对“基于对象(PP+ADT)编程范式”的致敬吧,虽然还是很想再写篇用纯C实现基于对象编程的系列,不过也可能要沉浸在ruby(或者其他更好的OO语言)带给我的“面向对象编程范式”的盛宴之中呢。。哈哈
C++ 我想这样用(七)的更多相关文章
- thusc2016游记&&滚粗记&&酱油记
#include <cstdio> using namespace std; int main(){ puts("转载请注明出处:http://www.cnblogs.com/w ...
- 【Beta】Daily Scrum Meeting总结
团队博客目录:FTD团队博客目录 一.项目预期计划和现实进展 更换网络请求框架为okHttp 完成 补充和完善服务器的API 完成(可与web端互连) 补充和完善app与服务器交互的类和方法 完成 完 ...
- iptables的详细介绍及配置方法*
Firewall(防火墙):组件,工作在网络边缘(主机边缘),对进出网络数据包基于一定的规则检查,并在匹配某规则时由规则定义的处理进行处理的一组功能的组件. 防火墙类型:根据工作的层次的不同来划分,常 ...
- TED Talk-教育如何扼杀创造力
TED上面有个"11个必须看的TED演讲"的播放列表,"教育扼杀创新"是其中一个.下面贴的是演讲的中文翻译. 早上好. 前面的演讲都很好,对不对? 我已经完全被 ...
- javascript+HTMl5游戏下载,开发一个都能月薪上万!舅服你
HTML5时代已经到来许久了,你是否已经掌握了那么一点呢?今天小编给大家讲讲h5的折叠多设备.跨平台特性, 即用HTML5制作游戏.相比flash,HTML5更加灵活方便,随着浏览器技术的不断升级,H ...
- wps 邮件 通讯小灵通 长沙杭州
记得在天涯上看过一个热贴,关于贵族与世家的,文中提到号称当今贵族的六大世家,什么“汝南周氏”.“吴兴沈氏”之类,更有甚者,为了比拼,追本溯源,把孔子他老人家也抬了出来,号称孔夫子的多少多少代传人,当时 ...
- R语言实现两文件对应行列字符替换(解决正负链统一的问题)
假设存在文件file1.xlsx,其内容如下: 存在文件file2.xlsx,其内容如下: 现在我想从第七列开始,将file2所有的字符替换成file1一样的,即第七.八.九.十列不需要改变,因为fi ...
- 【10.17校内测试】【二进制数位DP】【博弈论/预处理】【玄学(?)DP】
Solution 几乎是秒想到的水题叻! 异或很容易想到每一位单独做贡献,所以我们需要统计的是区间内每一位上做的贡献,就是统计区间内每一位是1的数的数量. 所以就写数位dp辣!(昨天才做了数字统计不要 ...
- 用python格式化小说txt
下载了<无人生还>的txt版.传到手机,发现阅读器识别得不够好. 原文格式如下: 第一章 一 沃格雷夫法官先生新近离任退休,现在正在头等车厢的吸烟室里,倚角而坐,一 边喷着雪茄烟,一边兴致 ...
- 小白学 Python 数据分析(11):Pandas (十)数据分组
人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...
随机推荐
- Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步
Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步 一.概述 PV操作是对信号量进行的操作. 进程同步是指在并发进程之间存在一种制约关系,一个进程的执行依赖另一个进程的消 ...
- 利用PhantomJS搭建Highcharts export服务
利用PhantomJS搭建Highcharts export服务 一直在使用Highcharts做web图表的展示, 但是当发送定时的报表邮件的遇到了这个问题. 为了保证邮件图表和web页图表样式一致 ...
- JDBC学习总结(四)
JDBC对LOB的读写 在JDBC中提供了java.sql.Blob和java.sql.Clob,两个类分别代表BLOB和CLOB数据. · BLOB(Binary Large Obj ...
- Java API —— 递归
1.方法定义中调用方法本身的现象 2.递归注意实现 1) 要有出口,否则就是死递归 2) 次数不能太多,否则就内存溢出 3) 构造方法不能递归使用 3. ...
- How to upgrade gcc using apt-get ?
在toolchain/test下已经有打包好的gcc,版本有4.x.5.0.6.0等,用这个PPA升级gcc就可以啦! 首先添加ppa到库: 1 sudo add-apt-repository ppa ...
- yeoman错误提示
运行 yo angular 出现如下提示: $ yo angular grunt-cli: The grunt command line interface. (v0.1.9) Fatal error ...
- Hibernate与Jpa的关系,终于弄懂
我知道Jpa是一种规范,而Hibernate是它的一种实现.除了Hibernate,还有EclipseLink(曾经的toplink),OpenJPA等可供选择,所以使用Jpa的一个好处是,可以更换实 ...
- MemSQL start[c]up Round 2 - online version(DP)
只有小写字母 那>=2600的直接找单字母串长度大于等于100的就可以了 <2600 的dp找最长回文串 #include <iostream> #include<cst ...
- Jqgrid入门-Jqgrid列数据拖动(七)
上一章提到在Jqgrid中如何设置二级表头,这一章节主要探讨Jqgrid表格里面的数据如果实现拖动功能,比如你想把第一行的数据拖到当前页的最后一行,或者其他位置. Jqgrid表格插件自己没有 ...
- 由于管理员设置的策略,该磁盘处于脱机状态-Win 2008 R2
问题截图: 做了个小说网站www.114369.cn,使用的是云主机,系统是Win 2008 R2,进入服务器后发现磁盘有问题 只有c盘,没有d盘,提示:由于管理员设置的策略,该磁盘处于脱机状态 解决 ...