- 公有继承:派生类对象可访问基类中的公有成员,派生类成员可访问基类中的公有成员与保护成员。
- 私有继承:对于派生类对象不可该问基类任何成员。派生类成员可该问基类公有与保护成员。所有基类公有与保护成员变成派生类私有成员,且不可为派生类的子类访问。基类私有成员对派生类不可见。
- 保护继承:派生类对象可访问基类中的公有成员,派生类成员可访问基类公有与保护成员。。基类的公有与保护成员变成派生类的保护成员,且不可为派生类的子类访问。基类私有成员对派生类不可见。
类继承默认私有继承。结构体继承默认公有继承。
以下转自:http://blog.csdn.net/huqinwei987/article/details/7525071
protectedInheritance.cpp
间接继承和书本描述不一致,书上说因为第一重继承变private,第二重继承才无法访问Base::i~是private,现实是提示Base::i是protected,好像跳过Private_derived类直接找基类了。
继承对基类的保护,还是普遍规律,只能越来越严,不能变松。
还有,标号不是限制派生类对基类成员(表达不清楚,是基类成员还是从基类继承过来的成员?)的访问,
原话:所有继承Base的类对Base中的成员具有相同的访问(指什么,成员?怎么理解恰当,派生类包括基类,所以这里的对基类访问指对派生类中包含的基类部分访问?)
标号是限制用户和派生类的派生类(也当作一种用户吧?)对派生类(从基类继承来的)成员的访问
- //公用、私有和受保护的继承
- #include<iostream>
- class Base{
- public:
- void basemem();
- protected:
- int i;
- };
- //struct直接继承class?可以?还有默认访问级别不同,一个public,一个private,转换后不要忘了
- struct Public_derived : public Base{
- int use_base() { return i; }//顾名思义,使用一下base看看
- };
- struct Protected_derived : protected Base{
- int use_base() { return i; }
- };
- struct Private_derived : private Base{
- int use_base() { return i; }//也没问题,尽管private~~~private不是设给它的,是给用户和下一个派生类的
- };
- //下一层派生
- struct Derived_from_Private : public Private_derived{
- int use_base() { return i; }
- //书上的注释,Base::i is private in Private_derived,
- //实际错误提示:'int Base::i' is protected,可能说明直接以用户身份去Base里找了,是protected,如果间接找,这个提示费劲
- };
- struct Derived_from_Public : public Public_derived{
- int use_base() { return i; }//可以访问,因为Base::i在Public_derived类中仍然是protected
- };
- int main(){
- Base b;
- Public_derived d1;
- Protected_derived d3;
- Private_derived d2;
- b.basemem();//b对象,肯定能访问
- d1.basemem();//对于d1对象,basemem()还是public
- //d2.basemem();//basemem()是private,不能访问
- //d3.basemem();//protected当然也不行了
- }
接口继承与实现继承:
public派生的类与基类有相同的接口。在设计良好的层次中,public派生的类可以用在任何需要基类对象的地方。
非public派生的类不继承基类的接口,称为实现继承,(用基类做它的实现,但不用基类做接口)
using.cpp
经过测试,using的用法和书上差距很大~!!!!!!!!!!!!!!!!!!(mark)
base的protected,用private继承,结果过用using可以变成public~~~!!!!
另:基类和派生类指针兼容与转换问题也测了一下,结果比较符合我“想当然”的判断。。
到底派生类的constructor怎么定义,把基类的成员用using声明了一遍,但是constructor的初始化列表会提示找不到成员n
- //派生类使用using声明恢复继承成员的访问级别。
- #include<iostream>
- class Base{
- public:
- std::size_t size() const { return n; }
- protected:
- std::size_t n;
- };
- class Derived : private Base{//private继承,全部成员变成私有
- public:
- using Base::size;
- //using Base::n;//神奇了,可以提升为public,直接d1.n就访问了。神奇的不是Geany编译器和g++吧
- protected:
- //using Base::n;
- private://声明成private也行啊。。。到底何谓“不能使访问级别比基类中原来指定的更严格或更宽松”
- using Base::n;//无论声明放在protected还是private后边,d1.n都提示n是protected。但public...
- //~小失误,把基类的n设为private,这种情况到底有何不同~恢复为private也有错啊?
- };
- class Public_derived : public Base{//private继承,全部成员变成私有
- public:
- //using Base::size;
- protected:
- //using Base::n;
- private:
- //using Base::n;
- };
- int main(){
- /*Base b1;
- Derived d1;
- Public_derived pd1;
- //猜测:一个对象的存储区域是顺序存放各类对象的,首地址是基类子对象,其次是派生类多出来的部分,再次是派生类的派生类。。。
- Base *bp1 = &d1;//private继承已经改变了基类的访问权限,所以基类指针也不能指向它了~“Base是Derived里不能访问的一部分”,因此public继承是一个前提。
- bp1 = &pd1;
- Public_derived *pdp1 = bp1; //前提:public。派生类的指针是不能指向基类的对象的,只能向下兼容
- Derived *dp1 = &b1; //不能向上兼容,所以和地址猜想不冲突,这说明很可能就是哪样排列的,所以不能分。
- */
- Derived d1;
- std::cout << d1.n;//这提升权限到public,但是无法初始化,我始终都搞不定派生类的初始化。。。
- }
默认继承保护级别(前边疑问的class和struct有解了):
default inheritance.cpp
比较简单的概念,默认不重要,自己可以手动设置
- //默认继承保护级别
- class Base{};
- struct D1 : Base{}; //public inheritance by default
- class D2 : Base{}; //private inheritance by default
- //这只是默认的,如果你每次都指定,还是无所谓。。。
- //原书:class和struct唯一的不同是默认的成员保护级别和默认的派生保护级别(这俩词指什么)
- //以下D3和D4的定义两两相同
- class D3 : public Base{
- public:
- /*...*/
- };
- //equivalent definition of D3
- struct D3 : Base { //inheritance public by default
- /*...*/ //initial number access public by default
- };
- struct D4 : Base {
- private:
- /*...*/
- };
- //equivalent definition of D4
- class D4 : Base { //inheritance private by default
- /*...*/ //initial member access private by default
- };
- //tips:因为私有继承在使用class保留字是默认情况,但因为实践中使用罕见,所以还要显式的使用private
- int main(){
- }
为何可以访问,却不可以利用构造函数初始化基类成员,派生类中的基类成员,莫非也用基类的构造函数来完成
- class Gif : public Picture_format{
- public:
- Gif(size_t i = 20) : pixels(i) {}
- size_t fcn(){ return pixels; }
- };
弄明白的东西:
继承来的成员的地位:
派生类的constructor无法在初始化列表中初始化继承成员,识别不到
对派生类对象来说,继承的成员也是基类的constructor初始化的,但是派生类能直接读取它,fcn()中使用pixels
如此说来,基类派生类貌似真是分开的模块
- class Picture_format{
- public:
- Picture_format(size_t i = 10) : pixels(i) {}
- protected:
- size_t pixels;//像素
- private:
- };
- class Gif : public Picture_format{
- public:
- size_t fcn(){ return pixels; }
- };
- //Gif g();//这个g不算类Gif的类对象,算个函数什么的吧?!
- Gif g;
- std::cout << g.fcn() << std::endl;