C++多层派生时的构造函数
一个类不仅可以派生出一个派生类,派生类还可以继续派生,形成派生的层次结构。在上面叙述的基础上,不难写出在多级派生情况下派生类的构造函数。
通过例下面的程序,读者可以了解在多级派生情况下怎样定义派生类的构造函数。相信大家完全可以自己看懂这个程序。
[例] 多级派生情况下派生类的构造函数。
#include <iostream> #include<string> using namespace std; class Student//声明基类 { public://公用部分 Student(int n, string nam)//基类构造函数 { num=n; name=nam; } void display( )//输出基类数据成员 { cout<<"num:"<<num<<endl; cout<<"name:"<<name<<endl; } protected://保护部分 int num;//基类有两个数据成员 string name; }; class Student1: public Student//声明公用派生类Student1 { public: Student1(int n,char nam[10],int a):Student(n,nam)//派生类构造函数 {age=a;}//在此处只对派生类新增的数据成员初始化 void show( ) //输出num,name和age { display( ); //输出num和name cout<<"age: "<<age<<endl; } private://派生类的私有数据 int age; //增加一个数据成员 }; class Student2:public Student1 //声明间接公用派生类Student2 { public://下面是间接派生类构造函数 Student2(int n, string nam,int a,int s):Student1(n,nam,a) {score=s;} void show_all( ) //输出全部数据成员 { show( ); //输出num和name cout<<"score:"<<score<<endl; //输出age } private: int score; //增加一个数据成员 }; int main( ) { Student2 stud(10010,"Li",17,89); stud.show_all( ); //输出学生的全部数据 return 0; }
运行时的输出如下:
num:10010 name:Li age:17 score:89
请注意基类和两个派生类的构造函数的写法。
基类的构造函数首部:
Student(int n, string nam)
派生类Student1的构造函数首部:
Student1(int n, string nam],int a):Student(n,nam)
派生类Student2的构造函数首部:
Student2(int n, string nam,int a,int s):Student1(n,nam,a)
注意不要写成:
Student2(int n, string nam,int a,int s):Student1(n,nam),student1(n, nam, a)
不要列出每一层派生类的构造函数,只需写出其上一层派生类(即它的直接基类)的构造函数即可。在声明Student2类对象时,调用Student2构造函数;在执行Student2构造函数时,先调用Student1构造函数;在执行Student1构造函数时,先调用基类Student构造函数。初始化的顺序是:
先初始化基类的数据成员num和name。
再初始化Student1的数据成员age。
最后再初始化Student2的数据成员score。
C++类多级派生时的访问属性
在实际项目开发中,经常会有多级派生的情况。如图11.9所示的派生关系:类A为基类,类B是类A 的派生类,类C是类B的派生类,则类C也是类A的派生类;类B称为类A 的直接派生类,类C称为类A的间接派生类;类A是类B的直接基类,是类 C的间接基类。
在多级派生的情况下,各成员的访问属性仍按以上原则确定。
为了把多重继承说的更加详细,请大家先看下面的几个继承的类。
[例] 如果声明了以下的类:
class A //基类 { public: int i; protected: void f2( ); int j; private: int k; }; class B: public A //public方式 { public: void f3( ); protected: void f4( ); private: int m; }; class C: protected B //protected方式 { public: void f5( ); private: int n; };
类A是类B的公用基类,类B是类C的保护基类。各成员在不同类中的访问属性如下:
根据以上分析,在派生类C的外面只能访问类C的成员函数f5,不能访问其他成员。 派生类C的成员函数f5能访问基类A的成员i、f2、j和派生类B的成员f3、f4。派生类B 的成员函数f3、f4能访问基类A的成员i、f2和j。
通过以上分析,可以看到:无论哪一种继承方式,在派生类中是不能访问基类的私有成员的,私有成员只能被本类的成员函数所访问,毕竟派生类与基类不是同一个类。
如果在多级派生时都采用公用继承方式,那么直到最后一级派生类都能访问基类的公用成员和保护成员。
如果采用私有继承方式,经过若干次派生之后,基类的所有的成员已经变成不可访问的了。
如果采用保护继承方式,在派生类外是无法访问派生类中的任何成员的。
而且经过多次派生后,人们很难清楚地记住哪些成员可以访问,哪些成员不能访问,很容易出错。因此,在实际中,常用的是公用继承。
主要内容:构造函数的调用顺序,基类构造函数调用规则前面我们说基类的成员函数可以被继承,可以通过派生类的对象访问,但这仅仅指的是普通的成员函数, 类的构造函数不能被继承。构造函数不能被继承是有道理的,因为即使继承了,它的名字和派生类的名字也不一样,不能成为派生类的构造函数,当然更不能成为普通的成员函数。 在设计派生类时,对继承过来的成员变量的初始化工作也要由派生类的构造函数完成,但是大部分基类都有 private 属性的成员变量,它们在派生类中无法
本文向大家介绍详解C++ 拷贝构造函数,包括了详解C++ 拷贝构造函数的使用技巧和注意事项,需要的朋友参考一下 拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于: 通过使用另一个同类型的对象来初始化新创建的对象。 复制对象把它作为参数传递给函数。 复制对象,并从函数返回这个对象。 如果在类中没有定义拷贝构造函数,编译器会自行定
由于派生类继承了其基类的成员,所以在建立派生类的实例对象时,必须调用基类的构造函数来初始化派生类对象的基类成员。派生类的构造函数既可以隐式调用基类的构造函数,也可以在派生类的构造函数中通过给基类提供初始化值(利用了前面所讲过的成员初始化值语法)显式地调用基类的构造函数。 派生类不继承基类的构造函数和赋值运算符,但是派生类的构造函数和赋值运算符能调用基类的构造函数和赋值运算符。 派生类的构造函数总是
本文向大家介绍详解C++中如何将构造函数或析构函数的访问权限定为private,包括了详解C++中如何将构造函数或析构函数的访问权限定为private的使用技巧和注意事项,需要的朋友参考一下 今天面试被问到了这个单例模式常用到的技术手段,下面进行分析: 很多情况下要求当前的程序中只有一个object。例如一个程序只有一个和数据库的连接,只有一个鼠标的object。通常我们都将构造函
本文向大家介绍解析C#中的私有构造函数和静态构造函数,包括了解析C#中的私有构造函数和静态构造函数的使用技巧和注意事项,需要的朋友参考一下 私有构造函数 私有构造函数是一种特殊的实例构造函数。它通常用在只包含静态成员的类中。如果类具有一个或多个私有构造函数而没有公共构造函数,则其他类(除嵌套类外)无法创建该类的实例。例如: 声明空构造函数可阻止自动生成默认构造函数。注意,如果您不对构造函数使用访问
和构造函数类似,析构函数也不能被继承。与构造函数不同的是,在派生类的析构函数中不用显式地调用基类的析构函数,因为每个类只有一个析构函数,编译器知道如何选择,无需程序员干涉。 另外析构函数的执行顺序和构造函数的执行顺序也刚好相反: 创建派生类对象时,构造函数的执行顺序和继承顺序相同,即先执行基类构造函数,再执行派生类构造函数。 而销毁派生类对象时,析构函数的执行顺序和继承顺序相反,即先执行派生类析构