私有继承

36 篇文章 1 订阅

实现has-a关系的途径:

  1. 包含(组合、层次化):类成员本身是另一个类的对象。
  2. 私有继承。
  3. 保护继承。

私有继承

在派生时,使用private关键字而不是public来定义类。
class Student:: private string, private valarray<double> {...};

  • 使用私有继承,基类的公有成员和保护成员都将称为派生类的私有成员。这意味着基类方法不会成为派生对象公有接口的一部分,但可以在派生类的成员函数中使用它们。
  • 使用私有继承时,只能在派生类的方法中使用基类方法。1
  • 私有继承中,要想将基类的引用或指针指向派生类,必须进行显式类型转换,将派生类指针或引用转换为基类指针或引用。(见下“私有继承的使用4”)
私有继承的使用
  1. 继承类的构造函数使用成员初始化列表语法时,私有继承使用类名而不是成员名来标志构造函数:
//包含:
Student(const char * str, const double *pd, int n)
	:name(str), scores(pd,n) {}
//私有继承:
Student(const char *str, const double *pd, int n)
	: string(str), ArrayDb(pd,n) {}
  1. 调用基类方法:包含使用对象名来调用基类方法;私有继承使用类名和作用域解析运算符来调用方法。
//包含:
double Student::Average() const
{
	return scores.sum()/scores.size();
}
//私有继承:
double Student::Average() const
{
	return ArrayDb::sum()/ArrayDb::size();
}
  1. 访问基类对象:由于私有继承是未被命名的对象,所以需要使用强制类型转换
const string & Student::Name() const
{
	return (const string &) *this;
}

上述方法返回一个引用,指向用于调用该方法的Student对象中的继承而来的string对象。

  1. 访问基类的友元函数:私有继承中,通过显示转换为基类来调用正确的函数:
ostream & operator<<(ostream & os, const Student & stu)
{
	os<<(const string &) stu;
...
}
私有继承与包含:

同:

  • 私有继承与包含都只获得实现,不获得接口。

异:

  • 包含将对象作为一个命名的成员对象添加到类中;而私有继承将对象作为一个未被命名的继承对象添加到类中。
  • 见“私有继承的使用”。

该使用包含还是私有继承:

  1. 通常使用包含,它容易理解:包含作为显式命名的对象,代码可以通过名称引用对象,而私有继承使得关系更抽象;
  2. 包含能够包括多个同类的子对象,而私有继承不行。如果某个类需要3个string对象,可以使用包含声明3个独立的string成员,而私有继承中当对象都没有名称时将难以区分;
  3. 如果新类需要访问原有类的保护成员,必须使用私有继承;
  4. 如果需要重新定义虚函数,必须使用私有继承。
私有继承与保护继承:

区别主要在从派生类再派生出一另一个类时:

  • 使用私有继承,第三代类将不能使用基类的接口。因为基类的共有方法在派生类中将变成私有方法;
  • 使用保护继承,第三代类则可以使用基类的接口。因为基类的共有方法在第二代中将变成保护方法,带三代派生类可以使用它们。

  1. 想要像公有继承那样直接使用基类方法,见 使用using重新定义访问权限↩︎

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值