Effective C++学习第九天

条款32:确定你的public继承塑模出is-a模型

       class D(derived)以public形式继承class B(base),则每一个类型为D的对象同时也是一个类型为B的对象,反之不成立,因此B比D表现出更加一般化的概念,而D比B表现出更特殊化的概念。在C++领域里面,任何函数如果希望获得一个类型为B的实参,都也愿意接受一个类型为D的对象,这就是is-a(是一种)的关系;代码分享:

class ractangle{

public:

virtual void setheight(int newheight);

virtual void setwidth(int newwidth);

virtual int height( ) const;

virtual int width( ) const;

};

void makebigger(rectangle &r){

int oldheight=r.height( );

r.setwidth(r.width( )+10);

assert(r.height()==oldheight);//assert为真

}

class square:public rectangle{ ...};

square s;

assert(s.width()==s.height( ));//assert为真

makebiggle(s);

assert(s.width()==s.height( ));//asseert为真 ,为什么s没有发生变化;

在本例分析中,某些可施行在矩形身上的事情(宽度可独立于高度被修改)却没办法施行在正方形身上(宽度和高度一样),但public主张,能够施行在base class对象上的每一件事情,都能施行于derived class对象上,所以正方形和矩形的例子中不满足is-a模型;pulic就意味着is-a模型,因此在继承中确定你的class之间的关系,并合理塑造它们

条款33:避免遮掩继承而来的名称(继承而导致的作用域问题)

          在public继承中,derived class中的成员函数会将base class中重名的成员函数覆盖掉,从而出现因继承导致成员函数调用问题;因此使用public继承但又不继承那些重载函数,这就违背了public继承中的is-a原则;

         如果你想继承base class并加上重载函数,而你希望重新定义或者复写其中一部分,那么你必须为那些原本会被遮掩的每个名称引用一个using的声明,否则某些你希望继承的名称会被遮掩;

         如果derived以private方式继承的base,如果使用using声明,那么给定名称的函数会在derived中都可见,这并不是我们希望达到的目的,这时候我们可以使用一个简单的转交函数;

class base{

public:

virtual void mf1()=0;

virtual void mf1(int);

...

};

class derived:private base {

public:

  virtual void mf1( ){//转交函数

        base::mf1( );//inline函数

 }

};

条款34:区分接口继承和实现继承

          public继承分为函数接口继承和函数实现继承;

          1)对于pure virtual函数,它有两个特性,它们必须被任何“继承了它们”的具象class重新声明,而且它们在抽象class中通常没有定义,因此声明一个pure virtual函数的目的是为了derived class只继承接口(只具体接口继承)

         引申:我们可以给pure virtual函数提供定义,也就是说你可以给base中的pure virtual函数提供一份实现代码,C++并不会发出警告和错误,但调用它的唯一途径就是:调用时明确指出其class路径;(一直以为pure virtual函数不能在base内实现)

         2)derived class继承函数接口,但是impure virtual函数会提供一份实现代码,derived class可能会赋写它;声明简朴的impure virtual 函数的目的,是让derived classes继承该函数的接口和缺省实现(具体指定接口继承和缺省实现继承);

         如果在继承过程中,derived class中没有重新定义virtual class,那么就默认使用base class中的virtual函数;如果两个class都共享着一份相同的性质,可以把这份相同的性质搬到base class中,从而避免代码重复,这是典型的面向对象的设计方法;

       3)对于一个non-virtual函数,意味着它并不打算在derived class中有不同的行为,实际上一个non-virtual成员函数所表现出来的不变性凌驾其特异性,因此不管derived class变得多特异化,它的行为都不可以被改变;声明一个non-virtual函数的目的是为了令derived class继承函数的接口及一份强制性的实现(具体指定接口及强制性实现继承);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/382384.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Effective C++学习第十天

条款36:绝不重新定义继承而来的non-virtual函数non-virtual函数执行的是静态绑定,在编译器就已经决定,因此对象对用的函数只和指针的类型有关,而与指针所指的对象无关;记住non-virtual函数的性质:不变性凌驾…

Redis运维和开发学习笔记(7) 内存管理和过期策略

Redis运维和开发学习笔记(7) 内存管理和过期策略 文章目录Redis运维和开发学习笔记(7) 内存管理和过期策略内存回收策略惰性删除定时任务删除maxmemory过期策略allkeys-lru主从搭建测试搭建完毕主从测试结果volatile-lru测试结果volatile-ttl测试结果allkeys-lru内存回收策略 …

Effective C++学习第十一天

条款41:了解隐式接口和编译期多态面向对象编程世界总是以显式接口(源码可见的接口)和运行期多态(virtual)解决问题;对于templates及泛型编程的世界,隐式接口和编译期多态显得更加重要&#xff1…

Redis源码分析(零)学习路径笔记

文章目录第一阶段第二阶段 熟悉Redis的内存编码结构第三阶段 熟悉Redis数据类型的实现第四阶段 熟悉Redis数据库的实现第五阶段 熟悉客户端和服务器端的代码实现第六阶段 这一阶段主要是熟悉Redis多机部分的代码实现关于测试方面的文件有一些工具类的文件如下SORT命令的实现一些…

Effective C++学习第十二天

条款47:请使用traits classes表现类型信息STL有五类迭代器分类,input迭代器(只读,一次,向前)、output迭代器(可写,一次,向前)、forward迭代器(读/…

Redis源码分析(一)redis.c //redis-server.c

Redis源码分析(一)redis.c //redis-server.c 入口函数 int main() 4450 int main(int argc, char **argv) {4451 initServerConfig();4452 if (argc 2) {4453 ResetServerSaveParams();4454 loadServerConfig(argv[1]);4455 …

Linux 学习

1.linux文本命令行语言环境设置命令 查看当前语言环境: echo ¥LANG 修改: LANG选择的语言环境’ 引申:https://blog.csdn.net/huoyunshen88/article/details/41113633 2.linux中的硬链接和软连接 linux中文件的储存方式&#xf…

vivo C/C++工程师视频面试总结 20180802

1.自我介绍:有点儿紧张了,直接把自己简历上的一些信息信息说了一遍,说完之后在介绍了一下自己的平时的爱好和兴趣,感觉面试官没有理我,直接进入下一环节了。 2.项目详情:主要是自己最近的一个项目和自己负…

Redis源码分析(二)redis-cli.c

文章目录1. int main()2. parseOptions(int argc, char **argv) 进行ip和port的改变3. lookupCommand(char *name) 查找命令,判断命令合法3.2 strcasecmp(name,cmdTable[j].name)3.1 redisCommand cmdTable[]4. cliSendCommand(int argc, char **argv)4.1 cliConnec…

C语言中有bool变量吗?

1.C/C中定义的数据类型: C语言中定义了6种基本数据类型:short,int,long,float,double,char 4种构造类型:数组,结构体(struct),共用类型(union),枚举类型(enum) 指针类型和空类型 C语…

redis源码剖析(三)——基础数据结构

文章目录SDS链表字典这篇文章关于 Redis 的基础数据:SDS SDS (Simple Dynamic String)是 Redis 最基础的数据结构。直译过来就是”简单的动态字符串“。Redis 自己实现了一个动态的字符串,而不是直接使用了 C 语言中的字符串。 sds 的数据结…

C++迭代器使用错误总结

指针和迭代器的区别: 迭代器: (1)迭代器不是指针,是类模板,表现的像指针。他只是模拟了指针的一些功能,通过重载了指针的一些操作符,->,*, --等封装了指针,是一…

redis源码剖析(四)跳表

文章目录整数集合跳跃表压缩列表总结整数集合 当一个集合只包含整数,且这个集合的元素不多的时候,Redis 就会使用整数集合 intset 。首先看 intset 的数据结构: typedef struct intset {// 编码方式uint32_t encoding;// 集合包含的元素数量…

vivo C/C++工程师 HR视频面试问题总结20180807

一开始没想到这次视频面是HR面试,还以为是技术面试,毕竟上次面试的时候技术问题问的相对比较少,所以面试准备方向有点儿错了,不过还是总结一下具体问题。 1)自我介绍:吸取了上次自我介绍的经验,…

在Redis客户端设置连接密码 并演示密码登录

我们先连接到Redis服务 然后 我们要输入 CONFIG SET requirepass “新密码” 例如 CONFIG SET requirepass "A15167"这样 密码就被设置成立 A15167 我们 输入 AUTH 密码 例如 AUTH A15167这里 返回OK说明成功了 然后 我们退出在登录就真的需要 redis-cli -h IP地…

redis源码剖析(五)—— 字符串,列表,哈希,集合,有序集合

文章目录对象REDIS_STRING (字符串)REDIS_LIST 列表REDIS_SET (集合)REDIS_ZSET (有序集合)REDIS_HASH (hash表)int refcount(引用计数器)unsigned lru:REDIS_LRU_BITS对象 对于 Re…

函数sscanf小结

1.sscanf用于处理固定格式的字符串&#xff0c;包含在头文件<cstdio>中&#xff0c;函数原型为&#xff1a; int sscanf(const char *buffer,const char*format,[]argument ]...); 其中:buffer代表着要存储的数据&#xff0c;format 代表格式控制字符串&#xff0c;arg…

redis源码剖析(六)—— Redis 数据库、键过期的实现

文章目录数据库的实现数据库读写操作键的过期实现数据库的实现 我们先看代码 server.h/redisServer struct redisServer{...//保存 db 的数组redisDb *db;//db 的数量int dbnum;... }再看redisDb的代码&#xff1a; typedef struct redisDb {dict *dict; /*…

多益网络 视频面试面试总结20180816

1.首先是自我介绍&#xff1a;因为等了半个小时&#xff0c;所以有点儿紧张&#xff0c;只说了一下自己的学校&#xff0c;爱好和兴趣&#xff1b; 2.介绍了一个自己的最成功的项目&#xff1a;我介绍了一个关于GPS导航的项目&#xff0c;介绍了项目的内容和项目的一些工作&am…

redis源码剖析(七)—— Redis 数据结构dict.c

文章目录dict.hdict.cdict.h //定义错误相关的码 #define DICT_OK 0 #define DICT_ERR 1//实际存放数据的地方 typedef struct dictEntry {void *key;void *val;struct dictEntry *next; } dictEntry;//哈希表的定义 typedef struct dict {//指向实际的哈希表记录(用数组开链的…