C++基础——类的继承

这篇博客深入探讨了C++中的继承概念,包括is-a关系、共有继承、私有继承和保护继承。文章详细解释了如何使用构造函数、析构函数以及虚函数实现多态,并强调了虚函数在动态联编中的作用。此外,还讨论了访问控制(public、protected、private的区别)以及继承与动态内存分配的关系。最后,通过实例展示了如何在实际代码中应用这些概念。
摘要由CSDN通过智能技术生成

1、初识继承

执行代码

#include <iostream>
#include "pingpong.h"
int main()
{
    std::cout << "Hello World!\n";
	using std::cout;
	pingpong player1("james", "hua", false);
	pingpong player2("lucy", "ling", true);
	//因为"james"与const string & 类型是不匹配的;
	//但是会通过两种方式使之有效
	//其一;将string作为pingpong的参数,将调用const string&作为参数的string 构造函数
	//其二;将c-风格字符串作为 pingpong的参数,将调用const char*作为参数的string 构造函数
	//二者取其一
	return 0;
}

pingpong 类

#include <iostream>
#include <string>
using namespace std;
class pingpong
{
private:
	string firstname;
	string lastname;
	bool hasTabel;
public:
	pingpong(const string &fn = "none", const string &ln = "none",bool ht=false);

	void SName()const;
	bool HasTable()const { return hasTabel; };
	void ResetTable(bool v) { hasTabel=v;};
};

//-----------------cpp的实现-----------------//
#include "pingpong.h"
pingpong::pingpong(const string &fn, const string &ln, bool ht):firstname(fn),lastname(ln),hasTabel(ht)
{//这也是继承
}
//和下面这个作用相同; 但是初始化,可以直接调用复制构造函数将  firstname 初始化为fn等等。
// 下面这个会多一步调用赋值运算符
//pingpong::pingpong(const string &fn, const string &ln, bool ht)
//{
//	firstname=fn; lastname =ln; hasTabel= ht;
//}
void pingpong::SName() const
{
	std::cout<<lastname << "," << firstname;
}

继承类RatedPlayer

#pragma once
#include"pingpong.h"

class RatedPlayer:public pingpong
{//: 指出它的基类是pingpong。ratedplay为派生类
 //: 使用共有派生,基类的公有成员成为派生类的共有成员
 //: 基类的私有部分,也会成为派生类的一部分;但是只能通过基类的共有和保护访问

	//需要添加自己的构造函数,据需求添加数据成员等等
private:
	unsigned int rating;
public:
	RatedPlayer(unsigned int r = 0,const string &fn = "none", const string &ln = "none", bool ht = false);
	RatedPlayer(unsigned int r, const pingpong &pg);

	unsigned int Rating()const { return rating; };
	void ResetRating(unsigned int r) { rating = r; };
};

//-----------------cpp的实现-----------------//
#include "RatedPlayer.h"
RatedPlayer::RatedPlayer(unsigned int r, const string &fn, const string &ln, bool ht):pingpong(fn,ln,ht)
{//把形参传递给pingpong的构造函数
	rating = r;
}
RatedPlayer::RatedPlayer(unsigned int r, const pingpong &pg) : rating(r), pingpong(pg)
{//将调用复制构造函数,由于没有申明它,所以就会调用 隐式的 pingpong ::pingpong(const pingpong &t)
  //因为不存在 new,调用隐式没问提
}

注意
//调用的时候

创建派生类对象时,程序首先调用基类的构造函数,然后调用自己的;
析构时,先调用自己的析构函数,在调用基类的析构函数

//关系

派生和基类的关系
a:派生类可以使用基类的方法(非私有的)
b:基类的指针可以在不进行显示转换时指向派生对象;基类的引用亦可;反之不行

代码演示

RatedPlayer s(1120, player2);//派生类
pingpong &ss = s;//基类

2、继承:is-a 关系

  • 共有继承
    即派生类也是一个基类的对象,可以对基类对象执行任何操作。
    继承只能添加东西,不能删除东西
  • 私有继承
  • 保护继承

3、多态继承和虚函数(方法)

虚函数;在基类中将会在派生类 中重新定义的方法;在基类中 声明虚函数,会被派生类自动声明成 虚方法。(建议还是加上virtual

简而言之,当你需要重新实现某个函数时,需要在基类中把它声明为 virtual

多态;同一个指针,可以指向不同的对象;

test 是一个基类
RatedPlayer s(1120, player2);
cout << player2.getlastName() << "\n";
	//多态的实现
pingpong *tt; //pingpong 是一个基类,RatePlayer是一个派生类
tt = new pingpong("james", "hua", false);
tt = new RatedPlayer(1120,"james", "hua", false);
//多态的实现

//虚析构函数 ,就是可以根据类型,去执行对应类的析构。
如果对应的成员有指针类型就需要释放。

4、静态联编和动态联编

静态联编;在编译过程中完成的;函数重载提升了编译时间
动态联编;在运行时,执行正确的代码这个过程。虚函数也提升了难度

  • 虚函数的工作原理

在编译类的时候,基类对象包含一个指针,指向基类中所有虚函数的地址表(所有虚函数都存在这张表中)

  • 在派生的时候;如果对虚函数有了新定义,将更新 虚函数表的地址;反之;则不更新

缺点与优点
缺:调用函数大的时候,都会去查表;每个对象都会增大,用来存储地址的空间;
优点:能够动态联编;即不同类型的类调用不同的虚函数。

哪些应该成为虚函数
1、在派生类中需要重新定义的
2、基类中有指针,需要被继承;则需要析构函数为虚函数。

5、访问控制

  • protected
  • private
    区别:在派生类的时候,可以直接访问protected的成员;不能访问 private的成员;
    对于不派生的情况,外界都不能访问。

6、继承与动态内存分配

知识点

只要类中有指针,就需要构造函数、析构函数、赋值运算符 中包含对指针的声明空间、以及释放
如果派生类中有指针,就需要显示调用析构、复制构造、赋值运算符

完整程序解读:

整合了继承、多态的使用;

链接:https://pan.baidu.com/s/11w-TCuQF84mtT8ThDvbg3g
提取码:zvbq

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值