精华内容
下载资源
问答
  • 不能被派生类继承的有
    千次阅读
    2016-07-21 17:03:05

    编辑器总是根据类型来调用类成员函数。但是一个派生类的指针可以安全转化为一个基类指针。这样删除一个基类的指针的时候,c++不管这个指针指向一个基类对象还是一个派生类对象,调用的都是基类的析构函数而不是派生类的。如果你依赖于派生类的析构函数的代码来释放资源,而没有重载析构函数,那么会有资源泄露。所以建议的方式是将析构函数声明为虚函数。也就是delete a的时候,也会执行派生类的析构函数。


    一个函数一旦声明为虚函数,那么不管你是否加上virtual修饰符,它在所有派生类中都成为虚函数。但是,由于理解明确起见,建议的方式还是加上virtual修饰符。


    构造方法用来初始化类的对象,与父类的其他成员不同,他不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但是不继承父类的构造方法)。因此,在创建子类对象的时候,为了初始化父类继承来的数据成员,系统需要调用其父类的的构造方法。


    如果没有显示的构造函数,编辑器会给一个默认的构造函数,并且该默认的构造函数仅仅在没有显示的声明构造函数情况下创建。


    构造原则如下:

    1、如果子类没有定义构造方法,则调用父类的无参数的构造方法。

    2、如果子类定义了构造方法,不论是无参数还是带参数,在创建子类的对象的时候,首先执行父类的无参数的构造方法,然后执行自己的构造方法。

    3、在创建子类对象的时候,如果子类的构造函数没有显示的调用父类的构造函数,则会调用父类的默认无参构造函数。

    4、在创建子类对象的时候,如果子类的构造函数没有显示调用父类的构造函数且父类自己提供了无参构造函数,则会调用父类自己的无参构造函数。

    5、在创建子类对象的时候,如果子类的构造函数没有显示调用父类的构造函数且父类只定义了自己的有参构造函数,则会出错(如果父类只有有参数的构造方法,子子类必须显示调用此带参构造方法)。

    6、如果子类调用父类带参数的构造方法,需要用初始化父类成员对象的方式。

    更多相关内容
  • C++类体系中,不能被派生类继承?

    万次阅读 多人点赞 2019-03-05 13:08:56
    C++类体系中,不能被派生类继承? 构造函数不能被继承,但是可以被调用。派生类的构造函数在初始化列表中应调用基类的构造函数。 --------------------- 为什么C++赋值运算符重载函数不能被继承? 这个问题...

    C++类体系中,不能被派生类继承的有?

    构造函数不能被继承,但是可以被调用。派生类的构造函数在初始化列表中应调用基类的构造函数。
    --------------------- 

    为什么C++赋值运算符重载函数不能被继承?

     

    这个问题曾经困扰过我一阵子。请先看一下下面的源代码:

    class A1
    {
    public:
             int perator=(int a)
             {
                     return 8;
             }
     
             int operator+(int a)
             {
                     return 9;
             }
    };
     
    class B1 : public A1
    {
    public:
             int operator-(int a)
             {
                     return 7;
             }
    };
     
    int main()
    {        
             B1 v;
             cout << (v + 2) << endl; // OK, print 9
             cout << (v - 2) << endl; // OK, print 7
             cout << (v = 2) << endl; // Error, see below
     
             return 0;
    }

    VC编译器的错误提示:

    error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'const int' (or there is no acceptable conversion)

    意思是说编译器找不到int perator=(int a)这个成员函数可以调用。

    真是怪了?明明int perator=(int a)这个函数是我从基类公有继承下来的函数,怎么编译器识别不了呢?遇到这种问题,第一反应就是查找MSDN以求得解释,微软告诉我:

    “All overloaded operators except assignment (operator=) are inherited by derived classes.”

    意思是说:除了赋值运算符重载函数以外,所有的运算符重载函数都可以被派生类继承。

    我这个函数int perator=(int a)很不幸就是微软所说的“赋值运算符重载函数”,当然不能被继承!

    可是到此为止,我心中的疑问依然没有消除。为什么“赋值运算符重载函数”不能被派生类继承呢?从C++语义上讲,不允许这个函数被派生类继承并没有充足的理由,一个类对象实例完全可以被任何一个其他类对象实例所赋值!比如一个颜色对象实例可以被一个整数赋值,甚至可以被一个小白兔实例所赋值。赋值运算符既然允许重载,就应该允许被继承,就像其他的运算符重载之后都可以被派生类继承一样。微软的解释并没有说明为什么“赋值运算符重载函数”不能被继承的幕后原因。

    我又查找了C++ Primer和其他一些重量级的C++经典,可是这些书籍对此问题都避而不谈,抑或是语焉不详,我都没有找到答案。于是,我只好反身求诸己,从C++类对象的构造开始分析,结果找到了我认为是正确的答案:

    1,每一个类对象实例在创建的时候,如果用户没有定义“赋值运算符重载函数”,那么,编译器会自动生成一个隐含和默认的“赋值运算符重载函数”。所以,B1的实际上的声明应该类似于下面这种情况
     

    class A1
    {
    public:
             int perator=(int a)
             {
                     return 8;
             }
     
             int operator+(int a)
             {
                     return 9;
             }
    };
     
    class B1 : public A1
    {
    public:
             B1& perator =(const B1& robj); // 注意这一行是编译器添加的
             int operator-(int a)
             {
                     return 7;
             }
    };

    2,C++标准规定:如果派生类中声明的成员与基类的成员同名,那么,基类的成员会被覆盖,哪怕基类的成员与派生类的成员的数据类型和参数个数都完全不同。显然,B1中的赋值运算符函数名operator =和基类A1中的operator =同名,所以,A1中的赋值运算符函数int perator=(int a);被B1中的隐含的赋值运算符函数B1& perator =(const B1& robj);所覆盖。 A1中的int perator=(int a);函数无法被B1对象访问。

    3,程序中语句v = 2实际上相当于v.operator =(2);,但是A1中的int perator=(int a);已经被覆盖,无法访问。而B1中默认的B1& perator =(const B1& robj);函数又与参数2的整数类型不相符,无法调用。

    4,为了确认B1中默认的B1& perator =(const B1& robj);函数的存在性,可以用以下代码验证:

    B1 b;
    B1 v;

    v = b; // OK, 相当于调用v.operator =(b);

    5,所以,“赋值运算符重载函数”不是不能被派生类继承,而是被派生类的默认“赋值运算符重载函数”给覆盖了。

    这就是C++赋值运算符重载函数不能被派生类继承的真实原因!

    关于本帖问题正确性的解释

    C++程序员的必读经典《Effective C++》这么说:

    条款45: 弄清C++在幕后为你所写、所调用的函数

    一个空类什么时候不是空类? ---- 当C++编译器通过它的时候。如果你没有声明下列函数,体贴的编译器会声明它自己的版本。这些函数是:一个拷贝构造函数,一个赋值运算符,一个析构函数,一对取址运算符。另外,如果你没有声明任何构造函数,它也将为你声明一个缺省构造函数。所有这些函数都是公有的。换句话说,如果你这么写:

    class Empty{};

    和你这么写是一样的:

    class Empty {
    public:
       Empty();                         // 缺省构造函数
       Empty(const Empty& rhs);         // 拷贝构造函数
     
     
       ~Empty();                        // 析构函数 ---- 是否
                                       // 为虚函数看下文说明
       Empty&
       perator=(const Empty& rhs);     // 赋值运算符
     
     
       Empty* operator&();              // 取址运算符
       const Empty* operator&() const;
    };

    但是Effective C++依然不能作为最后的判决。让我们从C++的“宪法”中寻找答案...

    ISO/IEC 14882是C++的国际标准。该标准于1998年9月1日通过并且定案。当然,这个标准已经不是最新标准了,但这个标准却是目前最被广泛支持的C++标准。所以,我一向称之为C++的“宪法”。

    C++“宪法”第12章 Special Member Functions (第185页)开宗明义:

    The default constructor, copy constructor and copy assignment operator, and destructor are special member functions. The implementation will implicitly declare these member functions for a class type when the program does not explicitly declare them, except as noted in 12.1. The implementation will implicitly define then if they are used, as specified in 12.1, 12.4 and 12.8. Programs shall not define implicitly-declared special member functions. Programs may explicitly refer to implicitly declared special member functions.

    译文:
    缺省构造函数,拷贝构造函数,拷贝赋值函数,以及析构函数这四种成员函数被称作特殊的成员函数。如果用户程序没有显式地声明这些特殊的成员函数,那么编译器实现将隐式地声明它们。12.1中有特别解释的例外。如果用户程序调用了这些特殊的成员函数,那么编译器就会定义这些特殊的成员函数,在12.1,12.4,12.8中分别规定了编译器对这些函数的定义方式。用户程序不能定义隐式声明的特殊成员函数。用户程序可以显式地调用隐式声明的特殊成员函数。

    译注:
    根据C++标准的规定:

    声明(Declare)代表头文件中的那部分代码,比如下面就是一个声明:
     

    class A
    {
    public:
         A();
    }

    定义(Define)代表源文件中的代码,比如下面就是一个定义:

    A::A()
    {}

     

    综上所述,可知,我的第一个说法是正确的。

    关于我的第二个说法的正确性,可参见C++“宪法”3.3.7 Name Hiding (第28页)(由于我手上的C++“宪法”是扫描版,无法直接拷贝文字,且文字较多,懒得输入了。)

    我的第3,4,5点说法都是常识性的知识,可以直接验证。

     

    转自:https://blog.csdn.net/chengonghao/article/details/51944979

    展开全文
  • C++ 类的继承与派生实例...继承与派生后,就了父类/基类与子类/派生类,C++中将类B称为父类/基类,将类A称为子类/派生类派生类的声明: #include using namespace std; class Student //基类的声明 { publ
  • 如果基类声明了私有成员,那么任何派生类都是不能访问它们的,若希望在派生类中能访问它们,应当把它们声明为保护成员。如果在一个类中声明了保护成员,就意味着该类可能要用作基类,在它的派生类中会访问这些成员。...
  • 92 典型例题分析与解答 例题 1下列对派生类的描述中 是错误的 A一个派生类可以作为另一个派生类的基类 B派生类至少一个基类 C派生类的成员除了它自己的成员外还包含了它的基类成员 D派生类继承的基类成员的访问...
  • 实验三 派生类继承 班级123班 姓名朱广金 学号122536 一实验目的 1学习类的继承能够定义和使用类的继承关系 2学习派生类的声明与定义方法 3掌握类的定义和对象的声明 4熟悉公有派生和私有派生的访问特性 5掌握派生...
  • 继承派生

    千次阅读 2022-03-27 20:43:57
    的对象只能访问的公有成员,不能访问私有成员及保护成员。 一、继承派生 在C++中,具有继承性,所谓继承就是在一个已存在的的基础上建立一个新的。 利用继承,可以将原来的程序代码重复使用,...

    类及对象的访问权限:

    类中的成员函数可以直接访问类中的数据成员(包括私有成员、公有成员、保护成员);

    类中的成员函数可以相互访问;

    类的对象只能访问类的公有成员,不能访问私有成员及保护成员。


     一、继承与派生

    在C++中,类具有继承性所谓继承就是在一个已存在的类的基础上建立一个新的类。

            利用类的继承,可以将原来的程序代码重复使用,从而减少了程序代码的冗余度,符合软件重用的目标。增强编程语言的功能。提高软件开发效率。

    在继承关系中,被继承的类称为基类(或父类把通过继承关系创建出来的新类称为派生类(子类)。

    派生类不仅可以继承原来类的成员,还可以通过以下方式产生新的成员:
    1.增加新的数据成员;
    2.增加新的成员函数;
    3.重新定义已有成员函数;
    4.改变现有成员的属性。


    继承的特点:

    1>继承具有层次结构。
    2>越在上面的类越具有普通性和共性,下层比上层更具体,越在下层越细化、专门化。
    3>继承具有传递性,即派生类能自动继承上层基类的全部数据结构及操作方法(数据成员及成员函数)

    基类与派生类的对应关系:

    单继承:

    一个派生类只从一个基类派生,这是最常见的继承形式

    多重继承;

    一个派生类有两个及两个以上的基类。如:类C从类A和类B派生。

    多重派生:

    由一个基类派生出多个不同的派生类。

    多层派生:

    每一个派生类又可以作为基类,再派生出新的派生类。

     基类和派生类之间的关系:

    1.基类是对派生类的抽象,派生类是对基类的具体化。基类抽取了它与派生类的公共特征,而派生类通过增加信息将抽象的基类变为某种具体的类型。
    2.派生类是基类的组合,可以把多重继承看作是多个单一继承的简单组合。

    二、派生类的声明方式

    定义派生类的一般形式:

    class 派生类名:继承方式 基类名

            派生类新增加的成员

    };

    继承方式有public(公有继承)、protected(保护继承)和private(私有继承)

    1. private方式继承(私有继承):

            基类中的公有成员和保护成员在派生类中皆变为私有成员。

    2.public方式继承(公有继承):

    基类的公有成员和保护成员被继承为派生类成员时,其访问属性不变。

    3.protected方式继承(保护继承):

    基类的公有成员和保护成员在派生类中成了保护成员,私有成员仍为基类私有。

    无论哪种继承方式,基类的私有成员均不能继承。这与私有成员的定义是一致的,符合数据封装的思想。

    三、派生类的构成

    1>在一个派生类中,其成员由两部分构成:

            1.从基类继承得到的成员

            2.自己增加的新成员

    2>友元关系不能继承。
    一方面,基类的友元对派生类的成员没有特殊访问权限。
    另一方面,如果基类被授予友元关系,则只有基类具有特殊访问权限,该基类的派生类不能访问授予友元关系的类。

    3>如果基类定义了静态成员
    无论从基类派生出多少个派生类,基类定义的静态成员,不受继承方式的影响,在整个类层次体系中都可以访问。

    4>派生类中访问静态成员,必须用显式说明

                    类名::成员

    一个派生类应包括4个方面:

    1)从基类接收成员

    除了构造函数和析构函数,派生类会把基类全部的成员继承过来。这种继承是没有选择的,不能选择接收其中一部分成员,而舍弃另一部分成员。

    2)调整基类成员的访问

    派生类接收基类成员是程序员不能选择的,但是程序员可以对这些成员作出访问策略。

    3)修改基类成员

    可以在派生类中声明一个与基类成员同名的成员,则派生类中的新成员会覆盖基类的同名成员,就实现了修改基类成员功能的效果。特别注意,如果是成员函数,不仅函数名相同,而且函数的参数个数和类型都要相同。

    4)在定义派生类时增加新的成员

    一般还应当自己定义派生类的构造函数和析构函数。

    派生类成员的访问属性

    私有成员只能被同一类中的成员函数访问。基类的成员函数不能直接访问派生类的成员。

    不同的继承方式决定了基类成员在派生类中的访问属性。

    公有继承:

    基类的公有成员和保护成员在派生类中保持原有访问属性,私有成员仍为基类私有。

    私有继承:

    基类的所有成员在派生类中为私有成员。

    保护继承:

    基类的公有成员和保护成员在派生类中成了保护成员,私有成员仍为基类私有。

    无论采用何种继承方式得到的派生类,派生类成员及其友元都不能访问基类的私有成员,派生类外部的用户只能访问公有属性的成员。
    多级派生的情况下,保护继承和私有继承会进一步地将基类的访问权限隐蔽成不可访问的。
    一般地,保护继承与私有继承在实际编程中是极少使用的,它们只在技术理论上有意义。


    四、公用继承

    基类的public和protected成员的访问属性在派生类中保持不变,但基类的private成员不可访问。

    派生类中的成员函数可以直接访问基类中的public和protected成员,但不能访问基类的private成员。

    通过派生类的对象只能访问基类的public成员。

    派生类的对象可以通过调用基类的公有成员函数访问基类的私有成员一一打通了派生类访问基类私有成员的消息通道。

     1) 通过调用基类的公有成员函数访问——直接消息通道

         格式:派生类对象. 基类公有成员函数名( )

           或:派生类对象.基类名::基类公有成员函数名( );

     2) 通过调用派生类公有成员函数,在公有成员函数中

        调用基类的公有成员函数访问。     ——间接消息通道

      格式:派生类对象->派生类公有成员函数->基类公有成

                  员函数->基类私有成员                           

                 

     五、私有继承

    基类的public和protected成员都以private身份出现在派生类中,但基类的private成员不可访问。
    在派生类中“私有化”,不能再继承,但在当前类内还可用。
    派生类中的成员函数可以直接访问基类中的public和protected成员,但不能访问基类的private成员。通过派生类的对象不能访问基类中的任何成员。

    派生类的对象不能访问基类的任何成员(公有成员在派生类中已变为私有,不能被对象访问)——隔断了派生类对象访问基类私有数据成员的消息通道;

    但在私有继承下可以在派生类中设置专门的成员函数调用基类的公有成员函数,通过其访问基类的私有成员。

    私有继承方式下,派生类对象访问基类私有成员的消息通路:

     派生类对象->派生类公有成员函数->基类公有成员函数->基类私有成员                              

                                                                                    —— 间接消息通道。

    访问保护成员:

    派生类对象->派生类公有成员函数->基类保护成员

                                                                            —— 间接消息通道。

     六、保护成员和保护继承

    基类的public和protected成员都以protected身份出现在派生类中,但基类的private成员不可访问。
    派生类中的成员函数可以直接访问基类中的public和protected成员,但不能访问基类的private成员。通过派生类的对象不能访问基类中的任何成员。

     protected 成员的特点与作用

    1.对建立其所在类对象的模块来说(水平访问时),它与 private 成员的性质相同。

    2.对于其派生类来说(垂直访问时),它与 public 成员的性质相同。

    3.既实现了数据隐藏,又方便继承,实现代码重用。        

    七、派生类成员的访问属性

    同名隐藏

    ——非virtual,同名同参或不同参

    ——virtual 同名不同参(同参就覆盖了)

    派生类定义了与基类同名的成员时,称派生类成员隐藏了基类的同名成员

    若在在派生类中使用基类的同名成员时,显式地使用类名限定符

                类名 :: 成员

    class base
    {
    public:
    	int a, b;
    
    };
    class derive :public base
    {
    public:
    	int b, c;
    };
    int main()
    {
    	derive d;
    	d.a = 1;
    	d.base::b = 2;//s使用base类的b
    	d.b = 3;//使用derive类的b
    	d.c = 4;
    	return 0;
    }

    派生类中的静态成员

    基类定义的静态成员,不受继承方式的影响,在整个类层次体系中都可以访问。

    派生类中访问静态成员,必须用以下形式显式说明

              类名 :: 成员

    三种继承方式之间的比较

     多级派生时的访问属性

    多级派生:每一个派生类又可以作为基类,再派生出新的派生类。

     特点:
    1.无论采用何种继承方式得到的派生类,在派生类中不能访问基类的私有成员,私有成员只能被本类的成员函数访问。
    2.如果在多级派生时都采用公有继承方式,直到最后一级派生类都能访问基类的公用成员和保护成员。

    八、派生类的构造函数和析构函数

    在定义派生类时,派生类并没有把基类的构造函数和析构函数继承下来。因此,对继承的基类成员初始化的工作要由派生类的构造函数承担,同时基类的析构函数也要被派生类的析构函数来调用。在创建派生类的对象时,由于派生类的对象包含了基类的数据成员.因此派生类的构造函数除初始化其自身定义的数据成员外.还必须对基类中的数据成员进行初始化。即派生类的构造函数要负责调用基类的构造函数。

    单继承派生类的构造函数

    单继承派生类构造函数的定义:

    在执行派生类的构造函数时,使派生类的数据成员和基类的数据成员同时都被初始化。

    定义形式为:

    派生类构造函数名(总形参表):基类构造函数名(参表

    {

            派生类新增数据成员初始化语句

    }

    说明:
    1.总形参表包含基类构造函数的参数和派生类新增的数据成员。

    2.基类构造函数名(实参表)是调用基类构造函数,而派生类新增加的数据成员可以在派生类初
    初始化,也可以在派生类初始化函数体中初始化。

    在建立对象时,派生类构造函数的执行顺序:

    ①在执行派生类构造函数时,先调用基类构造函数;
    ②再执行派生类构造函数;

    #include<iostream>
    using namespace std;
    #include<string>
    
    class student
    {
    public:
    	student(int n, string m, float s)
    	{
    		num = n; name = m; score = s;
    	}
    protected:
    	int num; string name; float score;
    };
    class student1 :public student
    {
    public:
    	student1(int n, string m, float s, int a, string sub) :student(n, m, s)
    	{
    		age = a; subject = sub;
    	}
    	void display();
    private:
    	int age;
    	string subject;
    };
    void student1::display()
    {
    	cout << "num:" << num << endl;
    	cout << "name:" << name << endl;
    	cout << "score:" << score << endl;
    	cout << "age" << age << endl;
    	cout << "subject:" << subject << endl;
    }
    int main()
    {
    	student1 stu(101, "zhangsan", 86, 18, "jisuanji");
    	stu.display();
    	return 0;
    }

    有子对象的派生类的构造函数

    类中的数据成员可以是类对象,类对象中的内嵌对象称为子对象,即对象中的对象

    说明:

    如果类A史有类B的子对象,类B有默认构造函数,或者参数全是默认参数的构造函数,或者有无参数的构造函数,那么类A的构造函数中可以不用显式初始化子对象。编译器总是会自动调用B的构造函数进行初始化。
    也可以在一个类的构造函数中显式地初始化其子对象,初始化式只能在构造函数初始化列表中。

    派生类中含有对象时构造函数的定义形式:

        派生类构造函数名(总参表): 基类构造函数名(参表)

         对象名(参表)

           派生类新增数据成员初始化语句   }

    在建立对象时,构造函数的调用顺序为

    调用基类构造函数,对基类数据成员初始化

    调用子对象构造函数,对子对象数据成员初始化

    执行派生类构造函数,对派生类数据成员初始化

    多层派生时的构造函数

    一个类不仅可以派生出一个派生类,派生类还可继续派生,形成派生的层次结构。

    和派生类的构造函数的表示

       构造函数名(参数表)  

               {  函数体   }

       派生1构造函数名(参数表): 基类构造函数名(参数表)   

               派生类新增数据成员初始化语句   }

       派生类2构造函数名(参数表): 派生类1构造函数名(参数表)   

            {  派生类新增数据成员初始化语句   }

    说明:在不要列出每一层派生类的构造函数,只须写出其上一层的构造函数。

    在建立对象时,构造函数的调用顺序为:

      在创建派生类2对象时,调用派生类2构造函数

      在执行派生类2构造函数先调用派生类1构造函数

      在执行派生类1构造函数时,先调用类构造函数

    展开全文
  • C++ 继承性:派生类

    千次阅读 2018-05-17 00:05:47
    C++继承性:派生类 继承继承是面向对象程序设计的一个重要机制,该机制自动地为一个类提供来自另一个类的操作和数据结构,这使程序员只需在新类中定义已类中没有的成员来建立新类。即,它允许在既类的基础...

    C++继承性:派生类

    1. 继承:继承是面向对象程序设计的一个重要机制,该机制自动地为一个类提供来自另一个类的操作和数据结构,这使程序员只需在新类中定义已有类中没有的成员来建立新类。即,它允许在既有类的基础上来创建新的类,新类可以从一个或多个既有类中继承函数和数据,可以重新定义或加进新的数据和函数,从而新类不但可以共享原有类的属性,并且具有新的特性,这样就形成类的层次。

    2. 在C++中,通过继承,可以让一个类拥有另一个类的全部属性,或者说是让一个类继承另一个类的全部属性。把被继承的类称为基类或者父类,而继承的类或者说是派生出来的新类称之为派生类或者子类。

    3. 如果对于一个派生类只有一个基类,称为单继承。如果同时有多个基类,称为多重继承。

    4. 特点:C++中类的继承层次自然地表达了人们分析问题时所用的分类结构,从而使得软件具有可重用性。大大改善了软件系统的可理解性和可维护性派生类实现了代码的重用,减少重复的工作量。

    5. 单继承:一般来讲,只有一个基类的派生类称为单继承,其形式如下:

      class派生类名:继承方式 基类名

      {

           派生类成员定义;

      };

      声明中的“基类名”是已有的类的名称,“派生类名”是继承原有类的特征而生成的新类名称。基类必须在声明派生类之前就已经声明过,否则会出现编译错误,“继承方式”制定了派生类成员以及类外对象对于派生类从基类继承来的成员的访问权限,其关键字为public,private和protected,分别表示它们的继承方式是公有继承(公有派生),私有继承(私有派生)和保护继承(保护派生),如果省略,系统将默认为私有继承

      1:公有继承访问权限特征:当类继承方式为公有继承时,基类中的公有成员和保护成员的访问权限在派生类中保持不变,而基类的私有成员不可访问。也就是说,基类的公有成员和保护成员被派生类继承过来作为派生类的公有和保护成员,而基类的私有成员在派生类中不能直接使用。

      #include<iostream>

      using  namespace std;

      classA   //基类A的定义

      {

           public:

               void setx(int m) {x=m;}

               void sety(int n) {y=n;}

               int getx() const{   return x;}

               int gety() const{   return y;}

           protected:

               int x;

           private:

               int y;

      };

      classB:public A//派生类B对基类A的公有继承

      {

      public:

           int getsum() {return x+gety();}//直接访问从基类继承来的保护成员x;但基类的私有成员y,只能通过接口函数访问

      };

      main()

      {

           B b;

           b.setx(5);

           b.sety(8);

           cout<<”X =”<<b.get()<<endl;//访问基类的公有成员函数

           cout<<”X+Y=”<<b.getsum()<<endl;//访问派生类的公有成员函数

      }

    6. 私有继承:当类继承方式为私有继承时,基类中的公有成员和保护成员都将以私有成员身份出现,基类的私有成员与公有继承相同,不可访问。也就是说,基类的公有成员和保护成员和保护成员被派生类继承过来作为派生类的私有成员,而基类的私有成员在派生类中不能直接使用。

      classA//基类A的定义

      {

           public:

               void setx(int m) {x=m;}

               void sety(int n) {y=n;}

               int getx() const{return x;}

               int gety() const{return y;}

           protected:

               int x;

           private:

               int y;

      };

      classB:private A//派生类B对基类A的私有继承

      {

           public:

               void setBx(int m) {x=m;}

               void setBy(int n) {y=n;}

               int getBx() const { return getx();}

               int getBy() const { return gety();}

               intgetsum() {return x+gety();} //直接访问从基类继承来的保护成员x,但基类的私有成员y,只能通过接口函数访问。

      };

      main()

    {

         B b;

         b.setBx(5);

    b.setBy(8);

    cout<<”X=”<<b.getBx()<<endl;

    cout<<”X+Y”<<b.getsum()<<endl;//访问派生类的公有成员函数

    }

    基类A派生出新的B类,其继承方式是私有继承。在基类A中声明的公有和保护的数据成员和成员函数被类B继承过来作为自身的私有成员。因此,派生类B的对象无法直接访问基类A中的任一成员。

    基类成员

    基类私有成员

    基类公有成员

    继承方式

    私有

    公有

    私有

    公有

    派生类成员

    不可访问

    不能访问

    可访问

    可访问

    外部函数

    不可访问

    不能访问

    不可访问

    可访问

    1. 保护继承:保护成员可以被派生类的成员函数访问,但是对于外界是隐藏起来的,外部函数不能访问它。当类继承方式为保护继承时,基类中的公有成员和保护成员都将以保护成员身份出现,基类的私有不可访问。也就是说,基类的公有成员和保护成员被派生类继承过来作为派生类的保护成员,而基类的私有成员在派生类中不能直接使用。

      公有成员----à保护成员

      保护成员----à保护成员

      私有成员----à不能直接使用

    2. 派生类的构造函数和析构函数:

      1:当创建派生类对象时,首先执行基类的构造函数,随后再执行派生类的构造函数;当撤销派生类对象时,析构函数的执行顺序则正好与构造函数的顺序相反,即先执行派生类的析构函数,随后再执行基类的析构函数。换句话说,构造函数按其引入的顺序执行,析构函数按其引入的相反顺序执行。

      2:当基类含有带参数的构造函数时,派生类的构造函数必须说明基类所需要的所有参数,其构造函数一般格式如下:

      派生类构造函数名(参数表):基类构造函数名(参数表)

    {

    ……

    }

    Eg:student(intn,char name[],char s,int a,char ad[]):stud(n,name,s)

    3:派生类构造函数后面括号内的参数表包括参数的类型和参数名。基类构造函数后面括号内的参数表只包括参数的参数名而不包括参数的类型。而派生类中含有对象成员时,其构造函数一般格式如下。

    派生类构造函数名(参数表):基类构造函数名(参数表),对象成员名(参数表)

    {

        ……

    }

    在定义派生类对象时,构造函数的执行顺序如下:

    1. 基类的构造函数

    2. 对象成员的构造函数

    3. 派生类的构造函数

    class stud//基类stud

    {

    proteted:

        int num;

        char name[10];

        char sex;

    public:

        stud(int n,char nam[],char s)

    {

        num=n;

        strcpy(name,nam);

        sex=s;

    }

    ~stud(){}

    };

    class student:public stud//派生类student

    {

        private:

            intage;

            charaddr[30];

        public:

            student(intn,char nam[],char s,int a,char ad[]):stud(n,nam,s)

    {

        age=a;

        strcpy(addr,ad);

    }

    voidshow()

    {

    cout<<”num:”<<num<<endl;

    cout<<”name:”<<name<<endl;

    cout<<”sex:”<<sex<<endl;

    cout<<”age:”<<age<<endl;

    cout<<”address:”<<address<<endl;

    }

    ~student(){ }

    };

    void main()

    {

        student(10010,”wang_li”,’f’,19,”115BeijingRoad,Shanghai”);

        student(10011,”Zhang_zhou”,’m’,20,”213BeijingRoad,Shanghai”);

    a.show();

    b.show();

    }

            4:1)由于析构函数是不带参数的,在派生类中是否要定义析构函数与它所属的基类无关,故基类的析构函数不会因为派生类没有析构函数而得不到执行,它们各自是独立的。

              2)当基类构造函数不带参数时,派生类不一定需要定义构造函数,然而当基类的构造函数带有至少一个参数,它所有的派生类都必须定义构造函数。

    9】多重继承:一个派生类有两个或者两个以上的基类的派生类称为多重继承或多继承。多继承可以看作是单继承的组合,单继承可以看作是多继承的特例。每一个基类必须制定其继承的方式,如果省略,相应的基类则取私有继承类型,而不是和前一个基类取相同的继承类型。各个基类构造函数的执行顺序取决于派生类时所制定的各个基类的顺序,而与派生类构造函数的成员初始化列表中给定的基类顺序无关。

    Egclass 派生类名:继承方式基类名1,继承方式 基类名2……,继承方式 基类名n

    {

            派生类成员定义;

    }

    class D:public A,public B,public C

    {

        ……

    }

    1. 虚基类:1:声明形式:class 派生类名:virtual派生类型 基类名

      Eg:  class B{private:int b;}

           class B1:virtual public B{private:int b1;};

           2:虚基类的应用:

               1)主要用来解决多继承时可能发生的对同一基类继承多次而产生的二义性问题。

               2)为最远的派生类提供唯一的基类成员,而不重复产生多次拷贝。

               3)在第一级继承时就要将共同基类设计为虚基类。

    展开全文
  • c++之哪些成员函数不能被继承

    千次阅读 2020-06-14 21:25:50
    C++中,并是所有的成员函数都被子类继承三类成员函数不能被子类继承,分别是:构造函数(包括拷贝构造)、析构函数、赋值运算符重载函数。 一,构造函数  构造方法用来初始化类的对象,与父类的其它成员...
  • 第十章 C#继承 派生类 派生类的构造方法.docx
  • 实验五:派生类继承(二).doc
  • C++派生类继承(超详细)

    万次阅读 多人点赞 2020-05-13 22:59:09
    派生类的概念 1.为什么要使用继承 继承性也是程序设计中的一个非常有用的、有力的特性, 它可以让程序员在既类的基础上,通过增加少量代码或修改少量代码的方法得到新的类, 从而较好地解决了代码重用的问题。 2.派生...
  • 如果基类中重写了赋值运算符重载函数,派生类中没有重写的话,那么当用派生类调用赋值运算符时,基类的运算符重载函数会调用,而且派生类的成员也会进行赋值。  如果基类中重写了赋值运算符重载函数,派生类中也...
  • c++课件 派生类继承

    2012-05-08 15:51:57
    c++课件 派生类继承
  • 1、单继承:class 派生类名:访问方式 基类名{ 派生类成员} 说明: 1.派生类名由用户自己命名 2.访问方式:公有、私有、保护 3.基类名必须是程序一个已的类 4.冒号:告诉系统,派生类从那个基类派生 5.派生类...
  • 派生类从基类继承的过程 派生类从基类继承的过程可以分为三个步骤:吸收基类成员、修改基类成员和添加新成员。 吸收基类成员就是代码复用的过程,修改基类成员和添加新成员实现的是对原有代码的扩展,而代码的复用和...
  • C++派生类继承方式 1.public:公有继承 采用公有公有继承方式创建的派生类对基类各种成员访问权限如下: (1)基类公有成员相当于派生类的公有成员, 即派生类可以象访问自身公有成员一样访问从基类继承的公有成员...
  • 派生类继承入门,这篇文章一定要认真看完。好好理解呀~
  •  继承性是面向对象程序设计的第二大特性,它允许在既有类的基础上创建新,新可以继承有类的数据成员和成员函数,可以添加自己特有的数据成员和成员函数,还可以对既有类中的成员函数重新定义。利用继承和...
  • C++派生类的构成 派生类中的成员包括从基类继承过来的成员和自己增加的成员两大部分。从基类继承的成员体现了派生类从基类继承而获得的共性,而新增加的成员体现了派生类的...派生类把基类全部的成员(包括构造函数
  • 派生类可以访问基类的public、protected成员,可以访问基类的private成员; 派生类对象可以访问基类的public成员,可以访问基类的protected、private成员。 protected继承 派生类可以访问基类的public、...
  • 实验2 派生类继承 实验课程名面向对象程序设计C++ 专业班级 计算机应用技术 学号 201130410115 姓名 熊柳强 实验时间 2012-10-9 实验地点 k4-207 指导教师 谢晋 一实验目的和要求 (1) 掌握派生类的声明方法和派生...
  • 继承派生总结

    2018-06-19 18:07:34
    c++继承与派生总结 面向对象的程序设计中提供了类的继承机制,允许...以原有的类为基础产生新的类,我们就说新类继承了原有类的特征,也就是说从原有类派生了新类。 类的派生机制的好处在于:代码的重用和可扩充性。
  • 1.不管以什么继承方式,派生类内部都不能访问基类的私有成员。 2.不管以什么继承方式,派生类内部除了基类的私有成员可以访问外,其他的都可以访问。 3.不管以什么继承方式,派生类对象除了公有继承基类中的...
  • 第9章 派生类继承.ppt
  • 而非公用派生类(私有或保护派生类不能实现基类的全部功能(例如在派生类不能调用基类的公用成员函数访问基类的私有成员)。因此,只有公用派生类才是基类真正的子类型,它完整地继承了基类的功能。 不同类型...
  • c++派生类继承实验报告

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 230,447
精华内容 92,178
热门标签
关键字:

不能被派生类继承的有