继承与派生的概念
- 继承所表达的是对象类之间的一种关系。它使得某类对象可以继承另外一类对象的特征和能力。
- 继承使得程序员对共同的属性及操作只需说明一次,减少了相似类的重复说明,并且在具体情况下可以扩展和细化 这些属性及操作。
保持已有类的特性而构造新类的过程称为继承。 - 在已有类的基础上新增自己的特性而产生新类的过程称为派生。
- 被继承的已有类称为基类(或父类)。
- 派生出的新类称为派生类 (或子类)。
继承的作用
在面向对象系统中,引入继承机制后具有的作用:
能减少代码和数据的重复冗余度,大大增加程序代码的复用性;
能清晰体现相关类间的层次结构关系;
对多个概念进行组合。
声明派生类
声明派生类的一般格式为:
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;
}