C++期末复习 继承和多态 自用

定义:

共有、私有、保护派生指的是基类中pulic和protected成员以什么形式出现子啊派生类中

知识查漏补缺:

派生类如若出现与父类同名的话 构造函数不能直接赋值否则会出现冲突

使用构造函数时,直接用父辈的就行

#include<bits/stdc++.h>
using namespace std; 
class TableTennisPlayer{

private:

string firstname;

string lastname;

bool hasTable;

public:

TableTennisPlayer( string  a,  string  b, bool f){
    hasTable=f;
    firstname=a;
    lastname=b;
};

string FirstName() const{
    return firstname;
}

string LastName() const{
return lastname;}

bool HasTable() const{return hasTable;
}

};

class RatedPlayer:public TableTennisPlayer{
    private:

        int rating;
    
    public:
        int Rating();
        RatedPlayer(int a,const string &b,const string &c,bool d):TableTennisPlayer(b,c,d),rating(a){
    
        
        }
};
int RatedPlayer::Rating(){
    return rating;

int main(){

string firstname, lastname;

bool hasTable;

int rating;

char flag;

while(cin>>flag){

if(flag=='T'){

cin>>firstname>>lastname>>hasTable;

TableTennisPlayer tp(firstname,lastname,hasTable);

if(tp.HasTable())

cout<<tp.FirstName()<<" "<<tp.LastName()<<" has a table.\n";

else

cout<<tp.FirstName()<<" "<<tp.LastName()<<" hasn't a table.\n";

} else if(flag=='R'){

cin>>firstname>>lastname>>hasTable>>rating;

RatedPlayer rp(rating,firstname,lastname,hasTable);

if(rp.HasTable())

cout<<rp.FirstName()<<" "<<rp.LastName()<<" has a table. The rating is "<<rp.Rating()<<".\n";

else

cout<<rp.FirstName()<<" "<<rp.LastName()<<" hasn't a table. The rating is "<<rp.Rating()<<".\n";

}

}

return 0;

}
再者,虚构函数如果提前出现把指针的内存空间删了的话 后续其他派生类就无法调用虚构函数了 

这里着重复习一下派生类虚构函数:

派生类析构函数
析构函数的作用是在对象撤销之前,进行必要的清理工作。
当对象被删除时,系统会自动调用析构函数。
析构函数的调用顺序与构造函数的调用顺序正好相反:
先执行派生类自己的析构函数;
然后调用子对象的析构函数;
最后调用基类的析构函数。
关于为什么需要虚析构函数: 

在C++中,虚析构函数非常重要,尤其是当涉及到使用多态和基类指针或引用时。下面是几个使用虚析构函数的理由,以及为什么直接写析构函数可能不足以处理所有情况:

1. **保证合适的析构顺序**:当你通过指向派生类的基类指针来删除对象时,如果没有定义虚析构函数,那么调用`delete`操作符可能会只析构基类部分而忽略派生类部分。这意味着派生类的资源不会被释放,从而导致内存泄漏。

2. **避免强制类型转换问题**:如果你有一个类型为基类的指针,但实际上指向派生类的对象,又由于基类的析构函数不是虚的,那么当它指向派生类时被删除,基类的析构函数会被调用来析构派生类的对象。这可能导致运行时错误。

3. **支持多态行为**:当你创建一个指向多态对象的基类指针并且想要删除这个对象时,虚析构函数可以确保按照继承层次由内到外依次调用析构函数,释放所有级别的资源。

4. **维持一定的设计准则**:在C++中,通常建议如果有虚函数(表明类涉及到多态),就应该将析构函数声明为虚函数。这是一种编程风格,可以保持代码的一致性,并帮助其他开发者理解你的类设计意图。

5. **接口的抽象性**:当类被设计为抽象基类时(也就是说,它包含纯虚函数),将析构函数声明为虚的允许派生类正确地析构,特别是在使用多态时。

6. **安全的向下转型**:如果基类的析构函数是虚的,安全性更高的向下转型(向下推理派生类,然后使用相匹配的析构函数)将变得可能。

因此,除非类明确地不被设计为基类(也就是说,你肯定没有人会从这个类派生新的子类),并且类没有虚函数,否则在实践中通常会将析构函数声明为虚函数。这样可以保证无论对象是通过基类指针或引用删除,都能确保调用正确的析构函数来准确和安全地清理资源。

 纯虚函数:

纯虚函数是C++中的一个抽象概念,它们在抽象类(也被称为接口或基类)中定义。一个纯虚函数是没有任何实现的虚函数,其目的是强迫派生类提供自己的实现方式。

纯虚函数的定义:

纯虚函数在声明时使用= 0来指示没有函数体。例如:

 

cpp复制代码

class Interface { public: virtual void pureVirtualFunction() = 0; };

特性和作用:

  1. 强制派生类实现:如果一个类包含至少一个纯虚拟函数,那么这个类就成为了抽象类,它不能被实例化。这意味着任何派生此类的子类必须实现所有的纯虚拟函数。这确保了子类对某些基础行为有自己的定义。

  2. 定义接口:纯虚拟函数用于定义一组相关功能的接口。不同的派生类可以根据自己的需求实现这个接口,从而实现多态性。

  3. 增强代码的灵活性:它们允许设计灵活的框架,使得你的代码不是刚性的,可以适应不同类型的对象行为。

  4. 促进良好的OOP实践:纯虚拟函数强制子类遵循接口规范,即它们必须提供特定行为的具体实现。

应用:

纯虚拟函数的应用场景非常广泛,以下是一些常见的应用案例:

  1. 接口规范:在一个由多种类型对象组成的系统(例如动物或车辆)中,如果不同的对象类型将表现出不同的行为,则可以使用接口规范来确保所有对象都有某些可预测的行为。

  2. 自动派生类生成逻辑:当需要让不同的子类在接收到某个触发条件时执行不同的逻辑时,纯虚拟函数非常适合。通过在基类中定义一个纯虚拟函数,并在子类中进行重写,可以实现特定的自动逻辑。

  3. 使用多态提供灵活性:在允许多种类型的对象共享相同类型的操作的情况下,可以将行为抽象化,并使用纯虚拟函数来定义这些行为。

  4. 设计模式中的实现:在某些设计模式中,可能会使用纯虚拟函数来实现特定的行为。例如,工厂方法模式中,工厂类就是一个抽象类,包含一个纯虚拟的创建对象的方法

#include <iostream>
#include <cmath>
using namespace std;

const double PI = acos(-1.0);

class Shape{
public:
    virtual double area() = 0;
};

class Circle : public Shape{
private:
    double r;
public:
    Circle(double r) :r(r){}
    double area(){ return PI*r*r; }
};

class rightTriangle : public Shape{
private:
    double x, y;
public:
    rightTriangle(double x, double y): x(x),y(y){}
    double area(){return (x*y)/2;}
};

class Rectangle : public Shape {
private:
    double length;
    double width;
public:
    Rectangle(double x, double y) : length(x), width(y){}
    double area(){ return width*length; }
};

int main()
{
    Circle c(3);
    rightTriangle t(3,4);
    Rectangle r(5, 4);

    Shape * p;
    p = &c;
    cout<<p->area()<<endl;
    
    p = &t;
    cout<<p->area()<<endl;
    
    p = &r;
    cout << p->area() << endl;

    p = NULL;

    return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值