C++Primer Plus 第十四章代码重用:14.2 私有继承002

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:

例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

14.2.2 使用包含还是私有继承

由于既可以使用包含,也可以使用私有继承来建立has-a关系,那么应使用种方式呢?大多数 C++程序员倾向于使用包含。首先,它易于理解。类声明中包含表示被包含类的显式命名对象,代码可以通过名称引用这些对象,而使用继承将使关系更抽象。其次,继承会引起很多问题,尤其从多个基类继承时,可能必须处理很多问题,如包含同名方法的独立的基类或共享祖先的独立基类。总之,使用包含不太可能遇到这样的麻烦。另外,包含能够包括多个同类的子对象。如果某个类需要3个string 对象,可以使用包含声明3个独
立的 string成员。而继承则只能使用一个这样的对象(当对象都没有名称时,将难以区分)。然而,私有继承所提供的特性确实比包含多。例如,假设类包含保护成员(可以是数据成员,也可以是成员函数),则这样的成员在派生类中是可用的,但在继承层次结构外是不可用的。如果使用组合将这样的类包含在另一个类中,则后者将不是派生类,而是位于继承层次结构之外,因此不能访问保护成员。但通过继承得到的将是派生类,因此它能够访问保护成员。
另一种需要使用私有继承的情况是需要重新定义虚函数。派生类可以重新定义虚函数,但包含类不能。
使用私有继承,重新定义的函数将只能在类中使用,而不是公有的。
提示:通常,应使用包含来建立 has-a 关系;如果新类需要访问原有类的保护成员,或需要重新定义虚函数,则应使用私有继承。

14.2.3 保护继承

保护继承是私有继承的变体。保护继承在列出基类时使用关键字protected:class

`Student:protected std::string.
protected std::valarray<double>`

使用保护继承时,基类的公有成员和保护成员都将成为派生类的保护成员。和私有私有继承一样,基考类的接口在派生类中也是可用的,但在继承层次结构之外是不可用的。当从派生类派生出另一个类时,有继承和保护继承之间的主要区别便呈现出来了。使用私有继承时,第三代类将不能使用基类的接口,这是因为基类的公有方法在派生类中将变成私有方法;使用保护继承时,基类的公有方法在第二代中将变成受保护的,因此第三代派生类可以使用它们。
表 14.1总结了公有、私有和保护继承。隐式向上转换(implicitupcasting)意味着无需进行显式类型转换,就可以将基类指针或引用指向派生类对象。
在这里插入图片描述

14.2.4 使用 using 重新定义访问权限

使用保护派生或私有派生时,基类的公有成员将成为保护成员或私有成员。假设要让基类的方法在派生类外面可用,方法之一是定义一个使用该基类方法的派生类方法。例如,假设希望Student 类能够使用valarray 类的 sum()方法,可以在 Student类的声明中声明一个sum()方法,然后像下面这样定义该方法:

double student::sum()const//public student method
return std::valarray<double>::sum();//use privately-inherited method

这样 Student 对象便能够调用 Student:sum(),后者进而将 valarray:sum()方法应用于被包含的valarray 对象(如果 ArrayDbtypedef在作用域中,也可以使用 ArrayDb 而不是 std::valarray)。另一种方法是,将函数调用包装在另一个函数调用中,即使用一个using声明(就像名称空间那样)来指出派生类可以使用特定的基类成员,即使采用的是私有派生。例如,假设希望通过Student 类能够使用 valarray 的方法 min()和 max(),可以在 studenti.h的公有部分加入如下 using 声明:

class Student :private std::string, private std::valarray<double>
s 
public :
using std::valarray<double>::minusing std::valarray<double>::max;
 

上述 using 声明使得 valarray::min()和 valarray:max()可用,就像它们是 Student 的公有方法一样:

cout<<"high score:"<<adali].max()<< endl;

注意,using 声明只使用成员名–没有圆括号、函数特征标和返回类型。例如,为使 Student 类可以使用 valarray 的 operator方法,只需在 Student 类声明的公有部分包含下面的 using 声明:using std::valarray::operator[];
这将使两个版本(const和非const)都可用。这样,便可以删除 Student::operator()的原型和定义using 声明只适用于继承,而不适用于包含。
有一种老式方式可用于在私有派生类中重新声明基类方法,即将方法名放在派生类的公有部分,如下所示:

class Student :private std::string, private std::valarray<double>
public :
	std::valarray<double>::operatorl];//redeclare as public, just use name.

这看起来像不包含关键字 using的using声明。这种方法已被摒弃,即将停止使用。因此,如果编译器支持using声明,应使用它来使派生类可以使用私有基类中的方法。

  • 27
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值