//############################################################################
/*
* 公有,保护,私有继承
*/ class B {
};
class D_priv : private B { }; //私有继承
class D_prot : protected B { }; //保护继承
class D_pub : public B { }; //公有继承 /*
不同的继承方法指定了派生类对基类不同的访问控制权限 上述三个派生类:
1. 都不能访问B中的私有成员.
2. D_pub继承B中的公有成员为公有,继承B中的保护成员为保护
3. D_priv继承B中的公有保护成员为私有
4. D_prot继承B中的公有保护成员为保护 转换:
1. 任何人都可以将一个D_pub*转换为B*. D_pub是B的特殊情况
2. D_priv的成员和友元可以将D_priv*转成B*
3. D_prot的成员,友元及子女可以将D_prot*转成B* 注意:只有公有继承是is-a的关系
*/ /* 详细实例 */ class B {
public:
void f_pub() { cout << "f_pub is called.\n"; }
protected:
void f_prot() { cout << "f_prot is called.\n"; }
private:
void f_priv() { cout << "f_priv is called.\n"; }
}; class D_pub : public B { //对于公有继承
public:
void f() {
f_pub(); // OK. D_pub的公有成员函数
f_prot(); // OK. D_pub的保护成员函数
f_priv(); // Error. B的私有成员函数
}
}; class D_priv : private B { //对于私有继承
public:
using B::f_pub; //使其在D_priv的作用域内可见
void f() {
f_pub(); // OK. D_priv的私有成员函数
f_prot(); // OK. D_priv 的私有成员函数
f_priv(); // Error. B的私有成员函数
}
}; int main() {
D_pub D1;
D1.f_pub(); // OK. f_pub()是D_pub的公有成员函数 D_priv D2;
D2.f_pub(); // Error. f_pub()是D_priv的私有成员函数,增加using B::f_pub之后OK B* pB = &D1; // OK 可以转换
pB = &D2; // Error 不能转换
...
} //############################################################################
/*
* 私有继承: 类似于has-a关系,跟组合类似
*/
class Ring {
virtual tremble();
public:
void tinkle() {...; tremble(); }
}; /* 组合 */
class Dog {
Ring m_ring;
public:
void tinkle() {m_ring.tinkle();} // 向前调用
}; /* 私有继承*/
class Dog_Priv : private Ring {
public:
using Ring::tinkle;
}; /*
* 组合的优点: 比如可以有多个ring,ring可以切换 //通常情况下倾向于组合,更低耦合,更灵活
* 私有继承的优点:更优雅的多态,比如
*
* 在ring类中增加虚函数tremble(), 该函数在tinkle中被调用
*/ /*
* 公有继承 => "is-a" 关系
*
* 基类能做的任何事情,派生类需要也能做
*/ //像以下类的设计就是不合适的
class Bird {
public:
void fly();
}; class Penguin : public Bird {}; Penguin p;
p.fly(); // class flyableBird : public bird {};
// public:
// void fly();
//penguin p;
//p.fly(); // 看几个例子
class Dog {
public:
void bark() { cout << "Whoof, I am just a dog.\n";};
}; class Yellowdog : public Dog{
public:
void bark() { cout << "Whoof, I am a yellow dog.\n";};
}; int main() {
Yellowdog* py = new Yellowdog();
py->bark();
Dog* pd = py;
pd->bark();
} OUTPUT:
Whoof, I am a yellow dog.
Whoof, I am just a dog.
/*
* 结论:不要覆写非虚函数
*/ class Dog {
public:
void bark(int age) { cout << "I am " << age; }
virtual void bark(string msg = "just a" ) {
cout << "Whoof, I am " << msg << " dog." << endl; }
}; class Yellowdog : public Dog {
public:
using Dog::bark;
virtual void bark(string msg="a yellow" ) {
cout << "Whoof, I am " << msg << " dog." << endl; }
}; int main() {
Yellowdog* py = new Yellowdog();
py->bark(5);
} OUTPUT:
Whoof, I am a yellow dog.
Whoof, I am just a dog. /*
* 不要重新定义虚函数的默认参数
* - 默认参数是静态绑定的
* - 虚函数是动态绑定的
*/ /*
* 在类dog中增加如下函数:
* virtual void bark(int age) { cout << "I am " << age << " years old"<< endl; }
* in main(),
* py->bark(5); // 编译不过
* // 可以通过在yellowdog中加"using Dog::bark;"修复 为了保持is-a关系
*/ // 防止意外覆写,或者没有覆写,增加了override关键字
class Dog {
public:
virtual void bark() { cout << "I am just a dog.\n";};
void run();
}; class Yellowdog : public Dog{
public:
virtual void barks() { cout << "I am a yellow dog.\n";}; //在旧标准中不会报错,等出错了调试比较困难
}; // C++ 11 standard:
class Yellowdog : public Dog{
public:
virtual void barks() override;
// 编译错误:没有覆写的函数 virtual void bark() const override;
// 编译错误:没有覆写的函数 void run() override; // 压根不是虚函数,错误
}; /*
* 避免采坑:
* 1. 类的精确定义
* 2. 不要覆写非虚函数
* 3. 不要覆写虚函数的默认参数
* 4. 强制继承被遮盖的函数
* 5. 小心函数覆写时的错字
*/

C++进阶--类的继承的更多相关文章

  1. Python类的继承(进阶5)

    转载请标明出处: http://www.cnblogs.com/why168888/p/6411918.html 本文出自:[Edwin博客园] Python类的继承(进阶5) 1. python中什 ...

  2. 苹果新的编程语言 Swift 语言进阶(十)--类的继承

    一.类的继承 类能够从其它类继承方法.属性以及其它特性,当一个类从另外的类继承时,继承的类称为子类,它继承的类称为超类.在Swift中,继承是类区别与其它类型(结构.枚举)的基础行为. 1.1 .类的 ...

  3. Java+7入门经典 - 6 扩展类与继承 Part 1/2

    第6章 扩展类与继承 面向对象编程的一个重要特性: 允许基于已定义的类创建新的类; 6.1 使用已有的类 派生 derivation, 派生类 derived class, 直接子类 direct s ...

  4. Javascript 进阶 面向对象编程 继承的一个样例

    Javascript的难点就是面向对象编程,上一篇介绍了Javascript的两种继承方式:Javascript 进阶 继承.这篇使用一个样例来展示js怎样面向对象编程.以及怎样基于类实现继承. 1. ...

  5. Javascript 进阶 面向对象编程 继承的一个例子

    Javascript的难点就是面向对象编程,上一篇介绍了Javascript的两种继承方式:Javascript 进阶 继承,这篇使用一个例子来展示js如何面向对象编程,以及如何基于类实现继承. 1. ...

  6. 游戏编程之Unity常用脚本类的继承关系

    前言学习Unity开发引擎的初学者会接触大量的脚本类,而这些类之间的关系往往容易被忽略.本文对Unity引擎开发中的一些常用类及其关系进行了简单的归纳总结. 博文首发地址:http://tieba.b ...

  7. Objective-C编程 — 类和继承

    讲述面向对象中的一个重要概念——继承,使用继承 可以方便地在已有类的基础上进行扩展,定义一个具有父 类全部功能的新类. 父类和子类 我们在定义一个新类的时候,经常会遇到要定义的新类是某个类的扩展或者是 ...

  8. C++学习笔记:07 类的继承与派生

    课程<C++语言程序设计进阶>清华大学 郑莉老师) 基本概念 继承与派生的区别: 继承:保持已有类的特性而构造新类的过程称为继承. 派生:在已有类的基础上新增自己的特性(函数方法.数据成员 ...

  9. UML类图(上):类、继承和实现

    面向对象设计 对于一个程序员来说,在工作的开始阶段通常都是别人把东西设计好,你来做.伴随着个人的成长,这个过程将慢慢变成自己设计一部分功能来实现,自己实现.如果要自己设计,无论是给自己看,还是给别人看 ...

随机推荐

  1. 九度OJ1111题-单词替换

    题目1111:单词替换 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6752 解决:1891 题目描述: 输入一个字符串,以回车结束(字符串长度<=100).该字符串由若干个单词组 ...

  2. 【算法】QuickSort

    快速排序,时间复杂度O(N*logN),要能熟练掌握! 以下主要参考http://blog.csdn.net/morewindows/article/details/6684558, 感谢原博主! 该 ...

  3. xdoj新生现场赛1269——带有限制条件的bfs 寻找最短路径

    bfss是解决最短路径的强大武器 (尝试dfs寻找最短路径 -(7*7)就会爆炸) 例题1  ccf 201604-4  游戏 问题描述 小明在玩一个电脑游戏,游戏在一个n×m的方格图上进行,小明控制 ...

  4. Hierarchical RNN

    https://blog.csdn.net/liuchonge/article/details/73610734 https://blog.csdn.net/triplemeng/article/de ...

  5. NYOJ 737:石子合并(一)(区间dp)

    737-石子合并(一) 内存限制:64MB 时间限制:1000ms 特判: No 通过数:30 提交数:37 难度:3 题目描述: 有N堆石子排成一排,每堆石子有一定的数量.现要将N堆石子并成为一堆. ...

  6. Linux 命令:文件目录操作与实例

    来源: http://blog.51cto.com/yuanzhitang/2056994 本文介绍基础的文件操作:创建,移动,编辑,删除 文件和文件夹   命令与案例:   mkdir 创建目录 - ...

  7. 直面Java 第002期

    . Java和C++同为面向对象语言,Java和C++主要区别有哪些?双方个有哪些优缺点? 解: C++ 被设计成主要用在系统性应用程序设计上的语言,对C语言进行了扩展.对于C语言这个为运行效率设计的 ...

  8. 紧接着上篇文章,实现类一个是标准的FIFO,一个是出队在头部入队不一定追加到末尾

    注意描述:一个是插入队列(1是可以插入尾部eg一遍的序列尾部追加,2是可以插入中间eg优先队列) 而移除的描素都是删除头部 import java.util.Comparator; import ja ...

  9. confluence 新tab 页面打开 kibana short link

    confluence 新tab 页面打开 https://confluence.atlassian.com/confkb/how-to-force-links-to-open-in-a-new-win ...

  10. splitChunks. cacheGroups 里面的 maxInitialRequests 含义

    entry文件请求的chunks不应该超过此值(请求过多,耗时) 出处:https://ymbo.github.io/2018/05/21/webpack%E9%85%8D%E7%BD%AE%E4%B ...