[C++] 继承、虚函数、纯虚函数、虚基类

1.继承

1.1.继承语法格式

要实现继承,遵循如下语法格式:

class SubClass : [public/protected/private] SuperClass
{
    
  //... 
};

其中SubClass称为派生类或子类,SuperClass称为基类或父类。
冒号之后的访问修饰符的作用如下:

  • 1.public表示公有继承,基类的公有成员将成为派生类的共有成员,基类的私有部分也将成为派生类的一部分,但只能通过基类的公有方法和保护方法访问;
  • 2.private表示私有继承,基类的共有成员和保护成员将成为派生类的私有成员,这将意味着基类方法将不会成为派生类对象公有接口的一部分,但可以在派生类的成员函数中使用他们。
  • 3.protected表示保护继承,它是私有继承的一个变体,基类的共有成员和保护成员将成为派生类的保护成员。

不管何种继承方式,基类的私有部分只能通过基类接口访问。

如果省略访问限定符,默认为private继承。

如:

//student.h:

#include <string>

class Person
{
   
private:
        int age;
        std::string name;
public:
        Person(int age = 0,std::string name="None");
        ~Person();
        void show() const;
};

class Student : public Person
{
   
private:
        double grade;
        std::string schoolname;
public:
        Student(int age = 0, std::string name = "None", double grade = 0.0, std::string schoolname = "None");
        Student(const Person & person, double grade = 0.0, std::string schoolname = "None");
        ~Student();    
        void show() const;
        void showSchoolName() const;//派生类添加方法
};

1.2.基类的构造函数能继承吗?

派生类可以继承到基类所有的公有部分和保护部分,但是构造函数除外。派生类不能继承基类的构造函数,同时,在创建派生类对象时,程序首先调用基类构造函数创建基类对象,再调用派生类构造函数。

正是由于这个原因,派生类的构造方法时,需要以成员初始化列表的方式将基类信息传递给基类构造函数,如我们定义Student的构造函数时:

Student::Student(int age, std::string name, double grade, std::string schoolname) : Person(age,name)
{
   
        std::cout << "Student::Student(int age, std::string name, double grade, std::string schoolname) call====" << std::endl;
        this->schoolname = schoolname;
        this->grade = grade;
}

如果省略成员初始化列表,那么当创建基类对象时,将使用默认基类构造函数,在这个构造函数中,可以省略成员初始列表,但在下一个构造函数中则不能省略了,如下:

Student::Student(const Person & person, double grade, std::string schoolname):Person(person)
{
   
        std::cout << "Student::Student(const Person & person, double grade, std::string schoolname) call====" << std::endl;
        this->schoolname = schoolname;
        this->grade = grade;
}

在这个构造函数中,使用Person(person),因此将调用基类的拷贝构造函数,由于没有提供拷贝构造函数,因此编译器将提供默认的拷贝构造函数来完成赋值。

在类设计时,派生类构造函数主要用于初始化新增的数据成员,继承的数据成员由基类构造函数初始化。

1.3.类型兼容性原则

派生类和基类有如下5种特殊关系:

  • 1.派生类对象可以使用基类的非私有方法;
  • 2.基类指针可以直接指向派生类对象;
  • 3.基类引用可以直接引用派生类对象;
  • 4.基于3得,基类对象可以使用派生类对象进行初始化;
  • 5.基于3得,派生类对象可以赋值给基类对象。

由于基类引用可以直接引用派生类对象,因此,当使用派生类对象初始化基类对象时:

Person p = s;

由于存在拷贝构造函数Person(const Person & p),从而可以得到第4点。

第5点也类似,由于存在隐式赋值运算符operator=(const Person &p ),故可以使p引用派生类对象。

以上5点称为类型兼容性原则。

我们对上例中student.h中声明的类进行实现,并通过这个例子来看看类型兼容性原则:

//student.cpp

#include <iostream>
#
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值