概要
在使用C++编译的过程中,继承几乎是随处可以见, 而且大部份继承也为公有继成。
公有继成的特点是:
父类所有进行继承,只是子类访问权限有一点改变,就是子类成员不能访问父类的私有数据成员。
还有一点是值得注意的:
子类成员是可以访问父类的protected 成员,而子类对象是不可以访问的。
效果
代码
person.h
#ifndef PERSON_H
#define PERSON_H
#include <iostream>
using namespace std;
class Person
{
public:
// Person();
Person(string name = "", string sex = "", string yearold = "");
virtual void tidian() = 0;
protected:
void showParam();
private:
string m_name;
string m_sex;
string m_yearold;
};
#endif // PERSON_H
student.h
#ifndef STUDENT_H
#define STUDENT_H
#include "person.h"
class Student : public Person
{
public:
Student(string name, string sex, string yearold, double grade);
void display();
private:
void tidian();
private:
double m_grade;
};
#endif // STUDENT_H
person.cpp
#include "person.h"
/*
Person::Person()
{
}
*/
Person::Person(string name, string sex, string yearold)
:m_name(name), m_sex(sex), m_yearold(yearold)
{
}
void Person::showParam()
{
cout << "the name is :" << m_name << endl;
cout << "the sex is :" << m_sex << endl;
cout << "the yearold is :" << m_yearold << endl;
}
#include "student.h"
Student::Student(string name, string sex, string yearold, double grade)
:Person(name, sex, yearold),
m_grade(grade)
{
}
void Student::display()
{
showParam();
cout << "the grade is:" << m_grade << endl;
}
void Student::tidian()
{
cout << "the tidian is hao chi" << endl;
}
main.cpp
#include <QCoreApplication>
#include "student.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Student student("lird", "man", "24", 95.5);
student.display();
return a.exec();
}
内容讲解
访问权限
首先可以看到Student是公有继承了Person
公有继承是子类拥有父类的所有数据成员,成员函数,除了构造器之外。 而对父类的私有数据, 子类是没有权限访问的。
私有数据成员
从上面的实例代码中,我们可以看到person类里面,有三个私有数据成员,这三个成员子类继承后也是不能访问的,只有通过调用对应的父类中包含此数据成员的成员函数,才能间接地访问它们。
保护类成员函数
Person类里面有一个protected成员函数, 当被公有继承后, 子类或父类的对象是不能调用它的。 但可以通过子类的成员函数,在函数内部调用。
纯虚函数
在Person类里面有一个公有的virtual void tidian() = 0;
这个是一个纯虚函数,纯虚函数就是只声明,不用定义。而子类里面,又必须要再次声明和定义, 否则编译不能通过。
构造器
既然是子类是继承父类,所以在子类对象生成时,必须初始化父类。 而父类的私有数据子类又是不能访问的,所以是不能通过
Student::Student(string name, string sex, string yearold, double grade)
:m_name(name),
m_sex(sex),
m_yearold(yearold),
m_grade(grade)
{
}
这种方式来进行初始化。
又因为子类并没有继承父类的构造器,所以
Student::Student(string name, string sex, string yearold, double grade)
:m_grade(grade)
{
Person(name, sex, yearold);
}
这种方式也行不通, 最后C++ 特定的自己的父类初始化:
Student::Student(string name, string sex, string yearold, double grade)
:Person(name, sex, yearold),
m_grade(grade)
{
}
就是通过构造列表来初始化。