21天学通C++之--继承实战练习

本文介绍了C++中的继承与派生概念,阐述了继承的作用,如减少代码冗余,增强代码复用性,以及派生类的声明格式。通过实际的题目,展示了继承在实际编程中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

继承与派生的概念

  • 继承所表达的是对象类之间的一种关系。它使得某类对象可以继承另外一类对象的特征和能力。
  • 继承使得程序员对共同的属性及操作只需说明一次,减少了相似类的重复说明,并且在具体情况下可以扩展和细化 这些属性及操作。
    保持已有类的特性而构造新类的过程称为继承。
  • 在已有类的基础上新增自己的特性而产生新类的过程称为派生。
  • 被继承的已有类称为基类(或父类)。
  • 派生出的新类称为派生类 (或子类)。

继承的作用

在面向对象系统中,引入继承机制后具有的作用:
能减少代码和数据的重复冗余度,大大增加程序代码的复用性;
能清晰体现相关类间的层次结构关系;
对多个概念进行组合。

声明派生类

声明派生类的一般格式为:
class 派生类名: 继承方式 基类名
{
// 派生类新增的数据成员和成员函数
……
};
其中“基类名”是一个已经定义的类的名称,“派生类名”是继承原有类的特性而生成的新类的名称。
“继承方式”表示如何访问从基类继承的成员,它可以是关键字private、protected和public,分别表示私有继承、保护继承和公有继承。由类Person派生出类Student可以采用后面三种格式


具体的对于继承其他知识:

函数重写,虚函数,抽象对象,动态绑定与静态绑定的知识就不写在这里了。


接下来直接贴题目和代码:

题目一

//
//  main.cpp
//  CppCP7_1
//
//  Created by Chenjun Xiong on 27/04/2017.
//  Copyright © 2017 Chenjun Xiong. All rights reserved.
//
//利用虚函数求面积
//
//题目描述
//定义抽象基类Shape,由它派生出3个派生类:Circle(圆形)、Rectangle( 长方形)、和Triangle (三角形),用虚函数分别计算面积。
//编写求面积和函数TotalArea (vector <Shape * >),该函数利用基类指针向量,它的每一个元素指向一个派生类的图形对象。
//编写测试解释器,读入各种图形信息,生成各种图形对象,由vector<Shape * > 管理。
//利用求面积虚函数,输出面积总和,要求正确释放空间。PI取3.1416
//
//输入描述
//circle 后跟半径
//rectangle后跟长和宽
//triangle后跟三条边
//
//输出描述
//结果保留小数点后4位
//
//输入样例
//circle  5.2 circle  6.0
//rectangle  3.4 2
//triangle  3 4 5
//rectangle  4.4 10
//
//输出样例
//254.8465

#include <iostream>
#include <math.h>
#include <vector>
#include <string.h>
#include <iomanip>
#define PI 3.1416;

using namespace std;
//below is shape class
class Shape{
protected:
    double area;
public:
    Shape(){area=-1;};
    virtual double CalArea(){return area;};
    double static TotalArea(vector <Shape*> &vecShapes);
    void static DeleteAllShapes(vector <Shape*> &vecShapes);
    virtual ~Shape(){};
};

double Shape::TotalArea(vector <Shape*> &vecShapes){
    double TotalArea=0;
    for(int index=0;index<vecShapes.size();index++){
        TotalArea+=vecShapes[index]->CalArea();
    }
    return TotalArea;
}

void Shape::DeleteAllShapes(vector <Shape*> &vecShapes){
    for(int index=0;index<vecShapes.size();index++){
        if(vecShapes[index])
            delete vecShapes[index];
    }
    while(vecShapes.size()>0){
        vecShapes.pop_back();
    }
    return;
}
//below is circle class
class Circle:public Shape{
private:
    double radius;
public:
    Circle(double radius);
    double CalArea();
    void static CircleBuilder(vector<Shape*> &vecShapes);
    ~Circle(){};
};

Circle::Circle(double radius):Shape(),radius(radius){
    CalArea();
}

double Circle::CalArea(){
    this->area=this->radius*this->radius*PI;
    return this->area;
}

void Circle::CircleBuilder(vector<Shape*> &vecShapes){
    double radius;
    cin>>radius;
    Circle *c=new Circle(radius);
    vecShapes.push_back(c);
//    c=NULL;
//    cout<<vecShapes[0]->CalArea();
    return;
}
//below is rectangle class
class Rectangle:virtual public Shape{
private:
    double height;
    double width;
public:
    Rectangle(double height,double width);
    double CalArea();
    void static RectangleBuilder(vector<Shape*> &vecShapes);
    ~Rectangle(){};
};

Rectangle::Rectangle(double height,double width):Shape(),height(height),width(width){
    CalArea();
}

double Rectangle::CalArea(){
    this->area=this->height*this->width;
    return this->area;
}

void Rectangle::RectangleBuilder(vector<Shape*> &vecShapes){
    double height,width;
    cin>>height>>width;
    Rectangle *r=new Rectangle(height,width);
    vecShapes.push_back(r);
    return;
}
//below is triangle class
class Triangle:virtual public Shape{
private:
    double side[3];
public:
    Triangle(double side1,double side2,double side3);
    double CalArea();
    void static TriangleBuilder(vector<Shape*> &vecShapes);
    ~Triangle(){};
};

Triangle::Triangle(double side1,double side2,double side3):Shape(){
    side[0]=side1;
    side[1]=side2;
    side[2]=side3;
    CalArea();
}

double Triangle::CalArea(){
    double p=(side[0]+side[1]+side[2])/2;
    this->area=sqrt(p*(p-side[0])*(p-side[1])*(p-side[2]));
    return this->area;
}

void Triangle::TriangleBuilder(vector<Shape*> &vecShapes){
    double sides[3];
    cin>>sides[0]>>sides[1]>>sides[2];
    Triangle *t=new Triangle(sides[0],sides[1],sides[2]);
    vecShapes.push_back(t);
}
//the main function
int main(int argc, const char * argv[]) {
    char shape[10];
    vector<Shape*> vecShapes;
    while(cin>>shape){
        if(strcmp(shape,"circle")==0){
            Circle::CircleBuilder(vecShapes);
        }else if(strcmp(shape,"rectangle")==0){
            Rectangle::RectangleBuilder(vecShapes);
        }else if(strcmp(shape,"triangle")==0){
            Triangle::TriangleBuilder(vecShapes);
        }
    }
    cout<<setiosflags(ios::fixed)<<setprecision(4)<<Shape::TotalArea(vecShapes)<<endl;
    Shape::DeleteAllShapes(vecShapes);
    return 0;
}

题目二

//
//  main.cpp
//  CppCP7_2
//
//  Created by Chenjun Xiong on 27/04/2017.
//  Copyright © 2017 Chenjun Xiong. All rights reserved.
//
//图像最佳匹配
//
//题目描述
//在某应用中, m × n 个像素灰度图像由 m × n 个正整数组成的矩阵表示,矩阵中每个整数元素表示一个像素。
//我们将两幅相同大小图像的差异度定义为各相同位置像素差的绝对值之和,将图像中某位置开始的m1 × n1矩形区域图像称为图像的子图像。给定m × n 个像素图像A和m1 × n1 个像素图像B,m〉=m1 且n 〉=n1, 现需要在图像A中查找与图像B具有最佳匹配(差异度最小)的大小为m1 × n1的子图像。
//
//设计程序,分别读入图像A和图像B数据,输出主图像A的子图像与图像B的最小差异度和相应子图像在主图象中位置(左上角行列号)。 如果满足要求的子图像有多个,请分别输出各子图像的位置。
//
//输入样例
//6 15
//213   66   28  226  131  243   24  250   77  159   62   77   72   17  250
//36  234  254  255  241   39  149  142  136  218   87  245  139  103   41
//86   38  158  167  169  253  227  188    4   99  140  111   26  205  139
//0    3  134   77   52   59  164  226  237  236   58   93  253  112  207
//126   60   17   15  142  217   20  193  139  237  247  249  133   86  246
//143   72  194  212  207   59   10  215  114  136  194   21  206  125   14
//
//3 4
//78   53   59  165
//16  119  209  20
//225  217  50   11
//
//输出样例
//68
     <4,4>
#include <iostream>
#include <math.h>
#include<limits.h>
using namespace std;

class ImageMap{
private:
    short **Map;
    short height;
    short width;
public:
    ImageMap();
    ImageMap(ImageMap const &b);
    ImageMap(short height, short width);
    void SetDotColor(short x,short y,short color);
    void SetMapColor();
    short GetDot(short x,short y)const;
    short GetHeight()const;
    short GetWidth()const;
    int static CalSingleFail(ImageMap const a,ImageMap const b,short x,short y);
    void static CalBestFit(ImageMap const a,ImageMap const b);
    ImageMap& operator=(ImageMap const &b);
    ~ImageMap();
};

ImageMap::ImageMap(){
    Map=NULL;
    height=0;
    width=0;
}

ImageMap::ImageMap(ImageMap const &b){
    this->height=b.GetHeight();
    this->width=b.GetWidth();
    this->Map=new short*[b.GetHeight()];
    for(int i=0;i<height;i++){
        this->Map[i]=new short[b.GetWidth()];
        for(int j=0;j<width;j++){
            this->Map[i][j]=b.GetDot(i,j);
        }
    }
}

ImageMap::ImageMap(short const height,short const width){
    this->height=height;
    this->width=width;
    this->Map=new short*[height];
    for(int i=0;i<height;i++){
        this->Map[i]=new short[width];
    }
}

void ImageMap::SetDotColor(short x, short y, short color){
    Map[x][y]=color;
}

void ImageMap::SetMapColor(){
    short color;
    for(int i=0;i<height;i++){
        for(int j=0;j<width;j++){
            cin>>color;
            SetDotColor(i, j, color);
        }
    }
}

short ImageMap::GetDot(short x, short y)const{
    return Map[x][y];
}

short ImageMap::GetWidth()const{
    return this->width;
}

short ImageMap::GetHeight()const{
    return this->height;
}

int ImageMap::CalSingleFail(ImageMap const a,ImageMap const b,short x,short y){
    int singlefail=0;
    for(int i=0;i<b.GetHeight();i++){
        for(int j=0;j<b.GetWidth();j++){
            singlefail+=abs(a.GetDot(x+i, y+j)-b.GetDot(i, j));
        }
    }
    return singlefail;
}

void ImageMap::CalBestFit(ImageMap const a, ImageMap const b){
    ImageMap p,q;
    if(a.GetHeight()>=b.GetHeight()&&a.GetWidth()>=b.GetWidth()){
        p=(a);
        q=(b);
    }else if(b.GetHeight()>=a.GetHeight()&&b.GetWidth()>=a.GetWidth()){
        p=(b);
        q=(a);
    }else{
        return;
    }
    int minfail=INT_MAX;
    const int x=p.GetHeight()-q.GetHeight()+1;
    const int y=p.GetWidth()-q.GetWidth()+1;
    int **failmap;
    failmap=new int*[x];
    for(int i=0;i<x;i++){
        failmap[i]=new int[y];
    }
    for(int i=0;i<p.GetHeight()-q.GetHeight()+1;i++){
        for(int j=0;j<p.GetWidth()-q.GetWidth()+1;j++){
            failmap[i][j]=CalSingleFail(p,q,i,j);
            if(failmap[i][j]<minfail){
                minfail=failmap[i][j];
            }
        }
    }
    cout<<minfail<<endl;
    for(int i=0;i<p.GetHeight()-q.GetHeight()+1;i++){
        for(int j=0;j<p.GetWidth()-q.GetWidth()+1;j++){
            if(failmap[i][j]==minfail){
                cout<<"<"<<i+1<<","<<j+1<<">"<<endl;
            }
        }
    }
    if(failmap!=NULL){
        for(int i=0;i<x;i++){
            delete[] failmap[i];
        }
        delete []failmap;
    }
}

ImageMap& ImageMap::operator=(ImageMap const &b){
    if(Map!=NULL){
        for(int i=0;i<height;i++){
            delete[] Map[i];
        }
        delete[] Map;
    }
    this->height=b.GetHeight();
    this->width=b.GetWidth();
    this->Map=new short*[b.GetHeight()];
    for(int i=0;i<height;i++){
        this->Map[i]=new short[b.GetWidth()];
        for(int j=0;j<width;j++){
            this->Map[i][j]=b.GetDot(i,j);
        }
    }
    return *this;
}

ImageMap::~ImageMap(){
    if(Map!=NULL){
        for(int i=0;i<height;i++){
            delete[] Map[i];
        }
        delete []Map;
    }
}

int main(int argc, const char * argv[]) {
    short x,y;
    cin>>x>>y;
    ImageMap a(x,y);
    a.SetMapColor();
    cin>>x>>y;
    ImageMap b(x,y);
    b.SetMapColor();
    ImageMap::CalBestFit(a, b);
    return 0;
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值