“大部分C++书籍都有三四百页厚,排版密密麻麻,你如果沉湎于它的细节之中,很容易迷失方向。”——《C专家编程》
下面试图通过一个小程序来全面接触C++的知识要点。
程序功能:输入n个数,输出n个数的排序。(下面有关这个程序的设计和编码,前面加SO标注)
要点一:抽象
抽象是一个去除对象中不重要的细节的过程,只有那些描述了对象的本质特征的关键点才被保留。抽象是一种设计活动,其他概念都是提供抽象的OPP特性。抽象建立了一种抽象数据类型,C++使用“类”这个特性来实现它。类就是用户定义类型加上所有对该类型进行的操作。
SO:定义一个“排序类”,其本质是接收数据、处理数据(一定的算法)。因此,定义一个Sort类,包含以下三个成员:
数组:int num[10];
数组:float num[10];
函数sortfun();
要点二:封装、访问控制
public:属于public的声明在类的外部可见。
protected:属于protected的声明只能由该类本身的函数以及从该类所派生的类的函数使用。
private:属于private的声明只能被该类的成员函数使用。
另外还有两个关键字会影响访问控制friend、virtual。
friend:属于friend的函数不属于类的成员函数,但可以像成员函数一样访问类的private和protected成员。friend可以是一个函数,也可以是一个类。
virtual:暂时搁置该话题。
原则:不要把类的数据成员做成public,因为让数据保持私有才符合面向对象编程的理论之一,只有类本身才能改变自己的数据,外部函数只能调用类的成员变量,这就保证了类的数据只会合乎规则的方式被更新。
SO:将num[10]声明为private。
要点三:重载(overload)
重载:指函数名相同,但参数不同(可能是类型、顺序、个数的不同)。有下面几个标准:
1) 在同一个作用域中(类内部);
2) 函数名相同;
3) 参数不同;
4) virtual关键字可有可无;
5) 返回值可以不同;
SO:实现sortfun()函数的重载。
要点四:继承
继承:从一个类派生另外一个类,使前者所有的特征在后者中自动可见。继承允许程序员使类型体系结构显式化,并利用它们之间的关系来控制代码。
SO:从Sort类派生一些子类,分别实现快速排序(SortQuick)、插入排序(SortInsert)、堆排序(SortHeap)、选择排序(SortSelection)、冒泡排序(SortBubble)。
要点五:重写(override)
重写:指派生类重新定义基类的虚函数。
1) 不在同一个作用域(分别位于派生类和基类);
2) 函数名相同;
3) 参数相同;
4) 基类函数必须有virtual关键字,不能由static;
5) 返回值相同;
6) 重写函数的访问修饰符可以不同;
SO:在子类中分别重写sortfun(),实现各自的排序算法。
要点六:多态
多态:在C++中,它的意思是支持相关的对象具有不同的成员函数(但原型相同),并允许对象与适当的成员函数进行运行时绑定。C++通过重写支持这种机制,当使用继承时就要用到这种机制:有时你无法在编译时分辨所拥有的对象到底是基类对象还是派生类对象,这个判断并调用正确的函数的过程被称为“后期绑定(late binding)”。在成员函数前面需要加上virtual关键字告诉编译器该成员函数是多态的。
排序程序的声明文件代码如下:
#ifndef SORT_H_
#define SORT_H_
#define N 10
//堆排序中公式的宏实现
#define LEFT(x) ((x<<1)+1)
#define RIGHT(x) ((x+1)<<1)
#define PARENT(x) (((x+1)>>1)-1)
//父类声明
class Sort {
private:
int num[N];
public:
//函数重载
virtual void sortfun(int num[]);
virtual void sortfun(int num[],int);
virtual void sortfun(int num[],int, int);
Sort();
~Sort();
};
//选择排序
class SortSelection:public Sort
{
private:
int num[N];
public:
void sortfun(int num[],int);
};
//冒泡排序
class SortBubble:public Sort
{
private:
int num[N];
public:
void sortfun(int num[],int);
};
//快速排序
class SortQuick:public Sort
{
private:
int num[N];
public:
void sortfun(int num[],int,int);
void swap(int *a, int *b);
};
//插入排序
class SortInsert:public Sort
{
private:
int num[N];
public:
void sortfun(int num[],int,int);
};
//堆排序
class SortHeap:public Sort
{
private:
int num[N];
public:
void sortfun(int num[],int); //sortHeap
void MaxHeap(int num[],int,int);
void BuildMaxHeap(int num[], int);
};
#endif
排序程序的定义文件代码如下:
#include "Sort.h"
#include <stdio.h>
//父类构造函数
Sort::Sort()
{
}
//父类析构函数
Sort::~Sort()
{
}
void Sort::sortfun(int num[])
{
}
void Sort::sortfun(int num[],int)
{
}
void Sort::sortfun(int num[],int, int)
{
}
//SortSelection子类重写排序函数,实现选择排序
void SortSelection::sortfun(int num[],int n)
{
int i,j,min,t;
for (i=0; i<n; i++)
{
min = i;
//查找最小的
for (j=i+1; j<n; j++)
{
if (num[min]>num[j])
{
min = j;
}
}
//交换
if (min!=i)
{
t = num[min];
num[min] = num[i];
num[i] = t;
}
}
}
//SortBubblex子类重写排序函数,实现冒泡排序
void SortBubble::sortfun(int num[],int n)
{
int i = n;
int j,temp;
while (i>0)
{
for (j=0; j<i-1; j++)
{
if (num[j]>num[j+1])
{
temp = num[j];
num[j] = num[j+1];
num[j+1] = temp;
}
}
i--;
}
}
//SortQuick子类重写排序函数,实现快速排序
void SortQuick::sortfun(int num[],int left,int right)
{
int i = left + 1;
int j = right;
int key = num[left];
if (left>=right)
{
return;
}
while (1)
{
while (num[j]>key)
{
j--;
}
while (num[j]<key&&i<j)
{
i++;
}
if (i>=j)
{
break;
}
swap(&num[i],&num[j]);
if (num[i]==key)
{
j--;
}
else
{
i++;
}
}
swap(&num[left], &num[j]);
if (left<i-1)
{
this->sortfun(num,left, i-1);
}
if (j+1 < right)
{
this->sortfun(num, j+1, right);
}
}
void SortQuick::swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
//插入排序
void SortInsert::sortfun(int num[],int first,int last)
{
int i,j;
int temp;
for (i=first+1; i<=last;i++)
{
temp = num[i];
j = i - 1;
while ((j>=first)&&(num[j]>temp))
{
num[j+1] = num[j];
j--;
}
num[j+1] = temp;
}
}
//堆排序
void SortHeap::MaxHeap(int num[], int nIndex, int nHeapSize)
{
int nL = LEFT(nIndex);
int nR = RIGHT(nIndex);
int nLargest;
int temp;
if (nL <= nHeapSize && num[nIndex] < num[nL])
{
nLargest = nL;
}
else
{
nLargest = nIndex;
}
if (nR <= nHeapSize && num[nLargest]<num[nR])
{
nLargest = nR;
}
if (nLargest != nIndex)
{
temp = num[nIndex];
num[nIndex] = num[nLargest];
num[nLargest] = temp;
MaxHeap(num, nLargest, nHeapSize);
}
}
void SortHeap::BuildMaxHeap(int num[], int nHeapSize)
{
for (int i=PARENT(nHeapSize); i>=0; i--)
{
MaxHeap(num, i, nHeapSize);
}
}
void SortHeap::sortfun(int num[],int nCount)
{
int temp;
int nHeapSize = nCount -1;
BuildMaxHeap(num, nHeapSize);
for (int i = nHeapSize; i>=1; --i)
{
temp = num[0];
num[0] = num[i];
num[i] = temp;
MaxHeap(num, 0, i);
}
}
排序主程序如下:
#include "Sort.h"
#include <stdio.h>
void main()
{
//输入数据
int num[N];
int a;
for (int i=0; i<N; i++)
{
scanf("%d", &a);
num[i] = a;
}
//处理数据(多态)
Sort *s;
s = new SortBubble;
s->sortfun(num,N);
//输出数据
printf("排序后的数据:\n");
for (int i=0; i<N; i++)
{
printf("%d ", num[i]);
}
}