精华内容
下载资源
问答
  • 基类成员在派生类继承情况

    千次阅读 2019-03-01 16:05:43
    公有继承的情况下,基类的public,protect成员的属性派生类保持不变,private成员的属性变为不可访问即派生类只能通过基类成员函数访问基类的私有成员。 私有继承的情况下,基类的public,...

    基类:public; protect; private;

    派生类公有继承基类:public; protect; 不可访问;

    派生类私有继承基类:private; private; 不可访问;

    公有继承的情况下,基类的public,protect成员的属性在派生类中保持不变,private成员的属性变为不可访问即派生类只能通过基类的成员函数访问基类的私有成员。

    私有继承的情况下,基类的public,protect成员的属性在派生类中变成私有,private成员的属性变为不可访问即派生类只能通过基类的成员函数访问基类的私有成员。

    展开全文
  • #include #include using namespace std; class Point { public:Point():x(0),y(0){}; Point(double x0,double y0):x(x0),y(y0){}; double returnx(){return x;... double returny(){return y;...
    #include <iostream>
    #include<cmath>
    using namespace std;
    class Point
    {
        public:Point():x(0),y(0){};
        Point(double x0,double y0):x(x0),y(y0){};
        double returnx(){return x;}
        double returny(){return y;}
        void PrintPoint();
        private :
        double x,y;
    };
    class Line:public Point
    {
        public:
        Line(Point pt,Point ps):pts(pt),pte(ps){};
        void PrintLine();
        private:
        class Point pts,pte;
    };
    void Point::PrintPoint()
    {
        cout<<"("<<x<<","<<y<<")"<<endl;
    }
    void Line::PrintLine()
    {
        double b;
        cout<<"直线两端点为:";
        pts.PrintPoint();
        pte.PrintPoint();
        cout<<endl<<"直线长度为:";
        b=sqrt((pts.returnx()-pte.returnx())*(pts.returnx()-pte.returnx())+
                   (pts.returny()-pte.returny())*(pts.returny()-pte.returny()));
        cout<<b;
        cout<<endl<<"直线中点为:";
        cout<<"("<<(pts.returnx()+pte.returnx())/2<<","<<(pts.returny()+pte.returny())/2<<")";
    }
    
    int main()
    {
        Point ps(-2,5),pe(7,9);
        Line l(ps,pe);
        l.PrintLine();
        return 0;
    }
    

    展开全文
  •  在保护继承方式基类的公有成员保护成员被派生类继承后变成派生类的保护成员,而基类的私有成员在派生类不能访问。因为基类的公有成员保护成员在派生类中都成了保护成员,所以派生类的新增成员可以直接...

           一.保护继承

           在保护继承方式中,基类的公有成员和保护成员被派生类继承后变成派生类的保护成员,而基类的私有成员在派生类中不能访问因为基类的公有成员和保护成员在派生类中都成了保护成员,所以派生类的新增成员可以直接访问基类的公有成员和保护成员,而派生类的对象不能访问它们,因为类的对象是处于类外的,不能访问类的保护成员对基类的私有成员,派生类的新增成员函数和派生类对象都不能访问。

           假设A类是基类,B类是从A类继承的派生类,A类中有保护成员,则对派生类B来说,A类中的保护成员和公有成员的访问权限是一样的。而对A类的对象的使用者来说,A类中的保护成员和私有成员都一样不能访问。可见类中的保护成员可以被派生类访问,但是不能被类的外部对象(包括该类的对象、一般函数、其他类等)访问。我们可以利用保护成员的这个特性,在软件开发中充分考虑数据隐藏和共享的结合,很好的实现代码的复用性和扩展性。

           举个简单的例子讨论下保护成员的访问属性。

    1.        class Base
    2.        {
    3.        protected:
    4.                   int x;           // 基类的保护成员
    5.        };
    6.        int main()
    7.        {
    8.                  Base base;
    9.                  base.x = 0;      // 编译报错
    10.                  return 0;
    11.        }

           这段代码在编译的时候会报错,错误就出在通过对象base访问保护成员x时,就像上面讲的,对Base类的对象base的使用者来说,Base类中的保护成员x和私有成员的访问特性是一样的,所以对象base不能访问x,这样跟使用私有成员一样通过保护成员实现了数据的隐藏

    1.         class Base
    2.         {
    3.         protected:
    4.                      int x;           // 基类的保护成员
    5.         };
    6.        class Child : public Base
    7.         {
    8.        public:
    9.                      void InitX();
    10.         };
    11.         void Child::InitX()
    12.         {
    13.                      x = 0;
    14.         }

           对上面的派生类Child来说,基类Base中的保护成员x和公有成员的访问权限一样,所以Child类的成员函数InitX可以访问Base类的保护成员x

    二.私有继承

           在私有继承方式中,基类的公有成员和保护成员被派生类继承后变成派生类的私有成员,而基类的私有成员在派生类中不能访问派生类的新增成员可以直接访问基类的公有成员和保护成员,但是在类的外部通过派生类的对象不能访问它们。而派生类的成员和派生类的对象都不能访问基类的私有成员

           我们看到不管是保护继承还是私有继承,在派生类中成员的访问特性都是一样的,都是基类的公有和保护成员可以访问,私有成员不能访问。但是派生类作为基类继续派生新类时,两种继承方式就有差别了。例如,A类派生出B类,B类又派生出C类,如果B类是以保护继承方式从A类继承的,则A类的公有成员和保护成员都成为B类的保护成员,再由B类派生出C类时,原来A类的公有成员和保护成员间接继承到C类中,成为C类的保护成员或者私有成员C类从B类公有继承或保护继承时为前者,私有继承时为后者),所以C类的成员可以间接访问A类的公有成员和保护成员。但是如果B类是以私有继承方式从A类继承的,则A类的公有成员和保护成员都成为B类的私有成员,A类的私有成员不能在B类中访问,B类再派生出C类时,原来A类的所有成员都不能在C类中访问。

            由以上分析得出,私有继承使得基类的成员在其派生类后续的派生中不能再被访问,中止了基类成员继续向下派生,这对代码的复用性没有好处,所以一般很少使用私有继承方式

           将之前的例子由公有继承改为私有继承,继而更形象的说明私有继承的特性。

    1.         #include <iostream>
    2.         using namespace std;
    3.         class Base            // 基类Base的声明
    4.          {
    5.          public:               // 公有成员函数
    6.                  void SetTwo(int a, int b)  { x=a; y=b; }
    7.                  int GetX()   { return x; }
    8.                  int GetY()   { return y; }
    9.         private:              // 私有数据成员
    10.                  int x;
    11.                  int y;
    12.         };
    13.         class Child : private Base    // 派生类的声明,继承方式为私有继承
    14.         {
    15.         public:                      // 新增公有成员函数
    16.                 void SetThree(int a, int b, int c)  { SetTwo(a, b); z=c; }
    17.                 int GetX()   { return Base::GetX(); }
    18.                 int GetY()   { return Base::GetY(); }
    19.                 int GetZ()   { return z; }
    20.         private:                     // 新增私有数据成员
    21.                 int z;
    22.         };
    23.         int main()
    24.         {
    25.                Child child;           // 声明Child类的对象
    26.                child.SetThree(1, 2, 3); // 设置派生类的数据
    27.                cout << "The data of child:"<<endl;
    28.                cout << child.GetX() << "," << child.GetY() << "," << child.GetZ() << endl; 
    29.                return 0;                                                         
    30.         }

           程序运行结果:

           The data of child:
           1,2,3

           Child类从Base类中私有继承,Base类中的公有成员SetTwo()、GetX()和GetY()成为Child类的私有成员在Child类中可以直接访问它们,例如Child类的成员函数SetThree()中直接调用了Base类的公有成员函数SetTwo()。Base类的私有成员x和y在Child类中不能访问。在外部通过Child类的对象不能访问Base类的任何成员,因为Base类的公有成员成为Child类的私有成员,Base类的私有成员在Child类中不能访问。那么Base类的作为外部接口的公有成员SetTwo()、GetX()和GetY()都被派生类Child隐藏起来,外部不能通过Child类的对象直接调用

           如果我们希望派生类也提供跟基类中一样的外部接口怎么办呢?我们可以在派生类中重新定义重名的成员。上面的Child类就重新定义了公有成员函数GetX()和GetY(),函数体则只有一个调用基类函数的语句,照搬了基类函数的功能。因为派生类中重新定义的成员函数的作用域位于基类中同名函数的作用域范围的内部,根据前面可见性中讲的同名覆盖原则,调用时会调用派生类的函数通过这种方式可以对继承的函数进行修改和扩展,在软件开发中经常会用到这种方法。

           main函数的函数体跟前面例子中的完全相同,但实际上在程序执行的时候是不同的,这里调用的函数GetX()和GetY()都是派生类Child的函数,由于是私有继承,基类Base中的同名函数都不能通过Child类的对象访问。

           这个例子跟前面的例子相比,Base类和主函数main的函数体都没有修改,只修改了派生类Child的声明,但Child类的外部接口没有改变。到此可以看到面向对象设计封装性的优越性。我们可以根据需要调整类的内部数据结构,但只要保持外部接口不变,那我们做的类的内部调整对外部就是透明的,不会影响到程序的其他部分。这充分体现了面向对象设计的可维护性和可扩展性。

         

    展开全文
  • 程序员面试宝典以及网上多个帖子上...可是,对于保护继承,应该是基类共有成员保护成员直接派生类中都变成了保护成员,但是保护成员不是还可以被直接派生类的子类访问吗?那就应该还可以继承下去呀,不解……
  • C++ 基类私有成员会被继承

    万次阅读 多人点赞 2015-11-05 00:51:24
    1.派生类间接访问继承私有成员在类的继承中,类的私有成员在派生类是“不可见“的,这种”不可见“是指派生类的成员函数,或者通过派生类的对象(指针,引用)不能直接访问它们。但是,不能直接访问并不代表不...

    1.派生类间接访问基类私有成员

    在类的继承中,基类私有成员在派生类中是“不可见“的,这种”不可见“是指在派生类的成员函数中,或者通过派生类的对象(指针,引用)不能直接访问它们。但是,不能直接访问并不代表不能访问。在派生类还是能够通过调用基类的共有函数的方式来间接地访问基类的私有成员,包括私有成员变量和私有成员函数。考察如下程序。

    #include <iostream>
    using namespace std;
    
    class A
    {
    	int i;
    	void privateFunc()
    	{
    		cout<<"this is a private function of base class"<<endl;
    	}
    
    public:
    	A(){i=5;}
    	int getI()
    	{
    		return i;
    	}
    
    	void usePrivateFunc()
    	{
    		privateFunc();
    	}
    };
    
    class B:public A
    {
    public:
    	void printBaseI()
    	{
    		cout<<getI()<<endl;
    	}
    	void usePrivateFunction()
    	{
    		usePrivateFunc();
    	}
    };
    
    int main()
    {
    	B b;
    	b.printBaseI();
    	b.usePrivateFunction();
    }
    

    程序输出结果:

    5
    this is a private function of base class
    

    在类 B 中,由于基类A的成员变量i和成员函数 privateFunc() 都是私有的,所以在类 B 的成员函数中无法直接访问到它们。但是,由于类 A 的公有成员函数 getI() 可以访问到私有成员变量 i,而 usePrivateFunction() 可以访问私有成员函数privateFunc(),所以在类 B 中通过调用函数 getI() 和 usePrivateFunc() 就可以间接访问基类 A 中的私有成员。

    2.私有成员会被继承吗

    如果基类中并没有提供访问私有成员的公有函数,那么其私有成员是否“存在“呢?还会不会被继承呢?其实,这些私有成员的确是存在的,而且会被继承,只不过程序员无法通过正常的渠道访问到它们。考察如下程序,通过一种特殊的方式访问了类的私有成员。

    #include <iostream>
    using namespace std;
    
    class A
    {
    	int i;
    	void privateFunc()
    	{
    		cout<<"this is a private function of base class"<<endl;
    	}
    
    public:
    	A(){i=5;}
    };
    
    class B:public A
    {
    public:
    	void printBaseI()
    	{
    		int* p=reinterpret_cast<int*>(this);//获取当前对象的首地址
    		cout<<*p<<endl;
    	}
    
    	void usePrivateFunction()
    	{
    		void (*func)()=NULL;
    		_asm
    		{
    			mov eax,A::privateFunc;
    			mov func,eax;
    		}
    		func();
    	}
    };
    
    int main() 
    {
    	B b;
    	b.printBaseI();
    	b.usePrivateFunction();
    }
    

    程序输出结果:

    5
    this is a private function of base class
    

    (1)虽然类 A 没有提供访问私有成员变量 i 的公有方法,但是在类 A(以及类 A 的派生类)对象中,都包含变量 i。
    (2)虽然类 A 并没有提供访问私有成员函数 privateFunc() 的公有函数,但是在程序代码区依然存有函数 privateFunc() 的代码,通过内联汇编获取该函数的入口地址,仍然可以顺利调用。

    综上所述,类的私有成员一定存在,也一定被继承到派生类中,从大小也可以看出派生类包含了基类的私有成员,读者可自行考证。只不过受到 C++ 语法的限制,在派生类中访问基类的私有成员只能通过间接的方式进行。


    参考文献

    [1] 陈刚.C++高级进阶教程[M].武汉:武汉大学出版社,2008[8.1节]

    展开全文
  • 1. 指向基类的指针可以指向派生类对象,当基类指针指向派生类对象时,这种指针只能访问派生对象从基类继承而来的那些成员,不能访问子类特有的元素,除非应用强类型转换,例如有基类B和从B派生的子类D,则B *p;...
  • 三种继承方式对于基类成员的访问权限是怎样的? 对于C++的继承方式共有三种: public继承 #include <string.h> #include <iostream> using std::cout; using std::endl; //定义一个基类 class Car { ...
  • 【任务1】理解基类中成员的访问限定符和派生类的继承方式 由下面派生类Student1对基类Student的继承…… (1)请修改基类中成员的访问限定符和派生类的继承方式,考虑可能的运行结果或可能出现的错误, 并上机...
  • 继承基类、派生类的访问属性

    千次阅读 2015-09-05 22:28:08
    一、单继承与多继承(1)一个派生类只从一个基类派生,这称为单继承(single inheritance);(2)一个派生类有两个或多个基类的称为多重继承(multiple inheritance);(注意:区分多重继承和多级派生的概念)二、声明...
  • 第二个步骤修改对基类成员的访问属性可以通过派生类的继承方式控制。 类的成员有public(公有)、protected(保护)和private(私有)三种访问属性。 类的继承方式也有public(公有继承)、protected(保护继承)...
  • 单一继承基类private虚函数派生类能否访问?? 用户程序,派生类对象的虚指针指向的虚函数表是仍然有基类private虚函数的条目,但是由于属性为private,无法实现正常的访问!// 通过得到private虚函数...
  • 小结:若是把基类的protected改为私有的,也就是下面的派生类不能访问基类中的私有成员提示错误,若是共有的,下面的一样访问 包括派生类外的也可有机会访问,若是把继承方式改为私有的或受保护的,则stud2.show( ...
  • 派生类从基类继承时有三个步骤,第一个步骤是吸收基类成员,吸收了基类中除构造函数和析构函数之外的所有数据成员和函数成员,第二个步骤就是修改基类成员,包括修改对基类成员的访问属性和覆盖基类成员,第三个步骤...
  • 这段时间笔者几篇文章介绍了改继承项目的文章. 关联文章的地址 每日一道理 风,那么轻柔,带动着小树、小草一起翩翩起舞,当一阵清风飘来,如同母亲的手轻轻抚摸自己的脸庞,我喜欢那种感觉,带有丝丝凉意,让人...
  • 知识点基类和派生类的定义派生类和基类的访问关系派生类对象对成员函数的调用派生类对象的存储派生类的构造派生类的构造函数派生类构造函数的调用顺序派生类的析构函数 基类和派生类的定义 从一个类派生出另一个类...
  • 【任务1】理解基类中成员的访问限定符和派生类的继承方式 由下面派生类Student1对基类Student的继承…… (1)请修改基类中成员的访问限定符和派生类的继承方式,考虑可能的运行结果或可能出现的错误, 并上机...
  • 我相信,如果当你点开这篇博客,说明你已经进入了c++的部分了,如果是刚刚开始学习继承的同学,我建议还是先看一下,我写的类和对象,先要了解一下,这里是进阶部分,害怕直接看同学有一点看懂。 类和对象:...
  • 含有虚函数成员(1)派生类不对基类的虚函数进行覆盖,同时派生类还拥有自己的虚函数派生类基类的虚函数进行覆盖(3)多继承:无虚函数覆盖(4)多重继承,含虚函数覆盖四.虚继承的情况 c++类的大小计算...
  • 继承情况下,来自不同父类的相同成员的访问问题 :假设子类继承自2个父类,这两个父类包含有同名的(数据)成员n,这时通过对象直接来访问该(数据)成员n时会出现什么问题? 从继承的角度讲,该数...
  • 1、普通多继承的内存布局 class A { public: int dataA; }; class B : public A { public: int dataB; }; class C : public A { public: int dataC; }; class D : public B, public C { public: int dataD;...
  • In member function 'void StudentB::showB()...(3)采用保护继承保护基类共有成员保护成员派生类中都成了保护成员,其私有成员仍为基类私有,也就是把基类原有的公有成员也保护起来,不让类外任意访问。
  • 派生类类内只可能访问基类的public和protected成员 派生类对象和基类对象只能访问自...基类成员在继承派生类的权限:  基类权限: public private protected  继承权限:public 继承 public private
  • 【任务1】理解基类中成员的访问限定符和派生类的继承方式 由下面派生类Student1对基类Student的继承…… (1)请修改基类中成员的访问限定符和派生类的继承方式,考虑可能的运行结果或可能出现的错误, 并上机...
  • 共有成员 保护成员 ...公有继承(public) ...1.注意理解所谓的可见性(如:基类的对象对基类共有成员可见) 2.派生类不可访问基类的私有成员 基类成员对派生类的可见性 √ √ ×
  • 派生类 内部/外部可否访问 (基类) 私有成员 公有成员 保护成员 私有继承 no/no yes/no yes/no 保护继承 no/no yes/no yes/no 若想要数据既具有私密性,又可被其它派生类成员函数访问, 就在基类中设置为...
  • 【任务1】理解基类中成员的访问限定符和派生类的继承方式由下面派生类Student1对基类Student的继承……(1)请修改基类中成员的访问限定符和派生类的继承方式,考虑可能的运行结果或可能出现的错误,并上机时进行...
  • c++初始化的顺序是由继承基类的顺序决定的。构造的顺序由继承列表决定。2.继承会继承属性(成员变量)和行为(处理方法)。3.3.继承方式:共有继承(public)保护继承(protect)私有继承(private)虚继承(virtual...
  • 纯虚函数 、抽象类 、多重继承 、二义性问题 、菱形继承 、虚基类 、从内存布局看虚继承的底层实现原理

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,721
精华内容 6,688
关键字:

在保护继承中基类的共有成员