C++ FAQ Lite[24]--继承(私有和保护继承)(更新)

原创 2001年06月01日 05:08:00

[24] 继承 — 私有继承和保护继承
(Part of C++ FAQ Lite, Copyright © 1991-2001, Marshall Cline, cline@parashift.com)

简体中文版翻译:申旻nicrosoft@sunistudio.com东日制作室东日文档


FAQs in section [24]:


[24.1] 如何表示“私有继承”?

: private 代替 : public,例如

 

 class Foo : private Bar {
 public:
   
// ...
 };

TopBottomPrevious sectionNext section ]


[24.2] 私有继承和组合(composition)有什么类似?UPDATED!

[Recently changed the syntax to using Engine::start; and added the sixth distinction thanks to Stan Brown; added the third similarity; added "aggregation" as another synonym; general wordsmithing (on 4/01). Click here to go to the next FAQ in the "chain" of recent changes.]

私有继承是组合的一种语法上的变形(聚合或者 “有一个”)

例如,“汽车有一个(has-a)引擎”关系可以用单一组合表示为:

 class Engine {
 public:
   Engine(int numCylinders);
   void start();                 
// Starts this Engine
 };
 
 class Car {
 public:
   Car() : e_(8) { }             
// Initializes this Car with 8 cylinders
   void start() { e_.start(); }  
// Start this Car by starting its Engine
 private:
   Engine e_;                    
// Car has-a Engine
 };

同样的“有一个”关系也能用私有继承表示:

 class Car : private Engine {    // Car has-a Engine
 public:
   Car() : Engine(8) { }         
// Initializes this Car with 8 cylinders
   using Engine::start;          
// Start this Car by starting its Engine
 };

两种形式有很多类似的地方:

  • 两种情况中,都只有一个 Engine 被确切地包含于 Car 中
  • 两种情况中,在外部都不能将 Car* 转换为 Engine*
  • 两种情况中,Car类都有一个start()方法,并且都在包含的Engine对象中调用start()方法。

也有一些区别:

  • 如果你想让每个 Car都包含若干 Engine,那么只能用单一组合的形式
  • 私有继承形式可能引入不必要的多重继承
  • 私有继承形式允许 Car 的成员将 Car* 转换成Engine*
  • 私有继承形式允许访问基类的保护(protected)成员
  • 私有继承形式允许 Car 重写 Engine 的虚函数
  • 私有继承形式赋予Car一个更简洁(20个字符比28个字符)的仅通过 Engine调用的start()方法

注意,私有继承通常用来获得对基类的 protected: 成员的访问,但这只是短期的解决方案(权宜之计

TopBottomPrevious sectionNext section ]


[24.3] 我应该选谁:组合还是私有继承? UPDATED!

[Recently changed so it uses new-style headers and the std:: syntax (on 7/00). Click here to go to the next FAQ in the "chain" of recent changes.]

尽可能用组合,万不得已才用私有继承

通常你不会想访问其他类的内部,而私有继承给你这样的一些的特权(和责任)。但是私有继承并不有害。只是由于它增加了别人更改某些东西时,破坏你的代码的可能性,从而使维护的花费更昂贵。

当你要创建一个 Fred 类,它使用了 Wilma 类的代码,并且Wilma 类的这些代码需要调用你新建的 Fred 类的成员函数。在这种情况下,Fred  调用 Wilma 的非虚函数,而Wilma 调用(通常是纯虚函数)被Fred重写的这些函数。这种情况,用组合是很难完成的。

 class Wilma {
 protected:
   void fredCallsWilma()
     {
       std::cout << "Wilma::fredCallsWilma()/n";
       wilmaCallsFred();
     }
   virtual void wilmaCallsFred() = 0;   
// 纯虚函数
 };
 
 class Fred : private Wilma {
 public:
   void barney()
     {
       std::cout << "Fred::barney()/n";
       Wilma::fredCallsWilma();
     }
 protected:
   virtual void wilmaCallsFred()
     {
       std::cout << "Fred::wilmaCallsFred()/n";
     }
 };

TopBottomPrevious sectionNext section ]


[24.4] 从私有继承类到父类需要指针类型转换吗?

一般来说,不。

对于该私有继承类的成员函数或者友元来说,和基类的关系是已知的,并且这种从PrivatelyDer* 到 Base* (或 PrivatelyDer& 到 Base&)的向上转换是安全的,不需要也不推荐进行类型转换。

然而,对于该私有继承类(PrivatelyDer)的用户来说,应该避免这种不安全的转换。因为它基于PrivatelyDer的私有实现,它可以自行改变。

TopBottomPrevious sectionNext section ]


[24.5] 保护继承和私有继承的关系是什么?UPDATED!

[Recently renamed "subclass" to "derived class" (on 7/00). Click here to go to the next FAQ in the "chain" of recent changes.]

相同点:都允许重写私有/保护基类的虚函数,都不表明派生类“是一种(a kind-of)”基类。

不同点:保护继承允许派生类的派生类知道继承关系。如此,子孙类可以有效的得知祖先类的实现细节。这样既有好处(它允许保护继承的子类使用它和保护基类的关联)也有代价(保护派生类不能在无潜在破坏更深派生类的情况下改变这种关联)。

保护继承使用 : protected 语法:

 

 class Car : protected Engine {
 public:
   
// ...
 };

TopBottomPrevious sectionNext section ]


[24.6] 私有继承和保护继承的访问规则是什么?UPDATED!

[Recently renamed "subclass" to "derived class" (on 7/00). Click here to go to the next FAQ in the "chain" of recent changes.]

以这些类为例:

 class B                    { /*...*/ };
 class D_priv : private   B { 
/*...*/ };
 class D_prot : protected B { 
/*...*/ };
 class D_publ : public    B { 
/*...*/ };
 class UserClass            { B b; 
/*...*/ };

子类都不能访问 B 的私有部分。在 D_priv中,B 的公有和保护部分都是私有的。在 D_prot中,B 的公有和保护部分都是保护的。在 D_publ 中,B 的公有部分是公有的,B 的保护部分是保护的(D_publ 是一种 B)。UserClass 类仅仅可以访问 B 的公有部分。

要使 B 的公有成员在 D_priv 或 D_prot中也是公有的,则使用 B:: 前缀声明成员的名称。例如,要使 B::f(int,float)成员在 D_prot中公有,应该这样写:

 class D_prot : protected B {
 public:
   using B::f;  
// 注意: 不是 using B::f(int,float)
 };

TopBottomPrevious sectionNext section ]


E-Mail E-mail the author
C++ FAQ LiteTable of contentsSubject indexAbout the author©Download your own copy ]
Revised Apr 8, 2001

C++继承类型:公有、保护、私有、虚拟

公有继承(public)、保护继承(protected)、私有继承(private)是常用的三种继承方式,除了这些继承类型外还有一种虚拟继承。...
  • shihengzhen101
  • shihengzhen101
  • 2015年11月22日 18:57
  • 656

C++ 公有继承、保护继承、私有继承的区别

1)基类成员对派生类的可见性 1. 公有继承(public) :基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的,不能被这个派生类的子类所访...
  • chlele0105
  • chlele0105
  • 2014年03月28日 17:05
  • 1516

公有继承,私有继承,保护继承的区别

一个子类继承父类时,可按照public、private和protected方式继承父类,每种继承方式的区别如下: 1) public继承方式 基类中所有public成员在派生类中为pu...
  • baowxz
  • baowxz
  • 2016年04月29日 16:01
  • 3875

C++ 公有继承、保护继承和私有继承中类成员的访问权限的控制

zz: http://blog.sina.com.cn/s/blog_b35e31b90101b6y7.html 为了防止连接失效,所以直接转过来备份了! 很多同学到现在仍然对访问权限不是很清楚,...
  • temanIU
  • temanIU
  • 2016年02月26日 16:21
  • 1401

C++ 公有(public)继承,私有(private)继承,保护(protected)继承

公有继承(public)、私有继承(private)、保护继承(protected)是常用的三种继承方式。 1. 公有继承(public) 公有继承的特点是基类的公有成员和保护成员作为派生类的成员...
  • u011040361
  • u011040361
  • 2015年05月06日 16:36
  • 355

C++:私有继承

C++:私有继承标签(空格分隔): c++C私有继承 私有继承 初始化基类组件 访问基类方法 访问基类对象 访问基类友元函数 应该使用包含还是继承 保护继承 重新定义访问权限 各种继承方式的比较 公...
  • qq_32583189
  • qq_32583189
  • 2016年09月08日 10:49
  • 866

C++中基类私有成员会被继承吗

1.派生类间接访问继承私有成员在类的继承中,类的私有成员在派生类中是“不可见“的,这种”不可见“是指在派生类的成员函数中,或者通过派生类的对象(指针,引用)不能直接访问它们。但是,不能直接访问并不代表...
  • K346K346
  • K346K346
  • 2015年11月05日 00:51
  • 5338

C++ 和C# 继承机制的差异之浅见

C++继承方式总共分为以下几种: public、private、protected三种(它们直接影响到派生类的成员、及其对象对基类成员访问的规则)。 (1)public(公有继承):继承时...
  • wangzhen199009
  • wangzhen199009
  • 2013年01月03日 13:18
  • 2519

C++箴言:谨慎使用私有继承

【简 介】 在《C++箴言:确保公开继承模拟“is-a”》一文中论述了 C++ 将 public inheritance(公有继承)视为一个 is-a 关系。当给定一个 hierarchy(继承体系...
  • jfkidear
  • jfkidear
  • 2013年12月26日 15:54
  • 642

浅析C++中的is-a和has-a关系(公有继承、包含、私有继承)

派生类和基类之间的特俗关系是基于C++继承的底层模型的。 总所周知,C++具有三种继承:公有继承、私有继承、保护继承。最常见的就是公有继承,它建立一种is-a的关系。 如何理解is-a呢?即派生类...
  • wangshubo1989
  • wangshubo1989
  • 2015年10月07日 22:09
  • 3393
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ FAQ Lite[24]--继承(私有和保护继承)(更新)
举报原因:
原因补充:

(最多只允许输入30个字)