1 派生类
派生类:利用继承机制,新的类可以从已有的类中派生。那些用于派生的类称为这些特别派生出的类的“基类”。
2 虚函数
虚函数可实现多态性 派生类只调用自己的函数。
下面来看示例:
class Stack{
public:
virtual void push(char c) = 0; // 虚函数 基类只有定义
virtual char pop() = 0;
};
基类只有原型的定义
class ArrayStack:public Stack{
char* p;
int maxSize;
int top;
public:
ArrayStack(int s)
{
top = 0;
maxSize = s;
//*****found*****1
//p=_____;
p = new char[s]; //为p申请s个char型空间
}
~ArrayStack()
{
//*****found*****2
//_____;
delete [] p; //释放指针 new的空间需要释放
}
void push(char c)
{
if(top == maxSize){
cerr<<"Overflow!n";
return;
}
//*****found*****3
//_____;
p[top] = c; //top为栈顶元素下标 添加的数据放到栈顶
top++;
}
char pop()
{
if(top == 0){
cerr<<"Underflow!n";
return ' ';
}
top--;
//*****found*****4
//_____;
return p[top];
}
};
派生类中,对push函数做了具体的实现。
那么 ,到底何时调用基类的虚函数,何时调用派生类的虚函数呢。这里可以做一个实验。
#include#include using namespace std; // 类定义 class A { public: virtual void print() { cout<<"这是基类A的print函数"< print(); p2->print(); return a.exec(); }
简单讲解一下,A是基类,B是派生类,print是虚函数。
先定义A类的实例aa,在定义B类的实例bb,然后定义基类指针p1和p2,再将aa和bb的地址赋予指针。这时候,p1输出的是A的函数,而p2输出的是B的函数。
虚函数的理论还是蛮绕的,就不误导观众了,这里最好找教材好好复习一下,这是个重要的知识点。
2 字符数组的开辟和销毁字符数组是本次学习的重点。
先来看下代码:
#include#include using namespace std; // 类定义 class Stack{ public: virtual void push(char c) = 0; // 虚函数可实现多态性 派生类只调用自己的函数 virtual char pop() = 0; }; class ArrayStack:public Stack{ char* p; int maxSize; int top; public: ArrayStack(int s){ top = 0; maxSize = s; p = new char[s]; //为p申请s个char型空间 } ~ArrayStack(){ delete [] p; //释放指针 new的空间需要释放 } void push(char c){ if(top == maxSize){ cerr<<"Overflow!n"; return; } p[top] = c; //top为栈顶元素下标 添加的数据放到栈顶 top++; } char pop(){ if(top == 0){ cerr<<"Underflow!n"; return ' '; } top--; return p[top]; } }; void f(Stack& sRef){ char ch[] = {'a','b','c'}; cout< 输出结果为
先来分析下类结构:
基类Stack 派生类ArrayStack char* p;
int maxSize;
int top;virtual void push(char c) = 0;
virtual char pop() = 0;ArrayStack(int s);
~ArrayStack();
void push(char c);
char pop();
基类实现了2个虚函数,1个是进栈push,1个是出栈pop。都是空的。
派生类实现了4个函数,分别是构造函数,析构函数,进栈push和出栈pop。
下面来看下main函数的逻辑
- 声明ArrayStack的对象as(10),这里要调用构造函数。
- 构造函数里,令top为0,maxSize为10,p开辟长度为10的字符数组变量
- 回到main,执行f函数,其形参是as。这里注意函数里是Stack类型,是基类。
- 在f函数里,as被传进来。声明了ch字符数组,其3个元素为a,b,c。首先cout这3个元素。控制台显示a,b,c。
- 对as执行push操作,进入push环节。这里也只能执行派生类的函数了。
- ch[0]是a,a进入push函数后,先做判断top == maxSize,这里目前是0==10所以否掉,执行p[top] = c;就是p[0]='a'。随后top自加变为1。
- 跳出push后,又来第2个push,变量是ch[1]就是b。继续。1==10不成立,所以p[1]='b' top=2。
- 再次push,这里判断2==3不成立,所以p[2]='c',top=3。
- 整理一下3次push的操作,ArrayStack对象as的p变量的前3个元素依次被赋予a,b,c三个字符。后面空着的8个元素还是空的。
- 下面执行pop操作。进入pop后,top=3,3==0不成立,跳过if,top变2,p[2]被返回,就是c。之后cout就是打印c
- 继续pop,top=2,2==0不成立,跳过if,top变1,p[1]=b被返回cout打印。
- 继续pop,top=1,1==0不成立,跳过if,top=0,p[0]=a被返回打印。
- f函数被执行完毕。返回main函数
- 执行完毕。程序退出,开始执行析构函数。
- 销毁p空间。
分析上述过程,p数组其实占用内存空间是固定的10个。pop后,也没有销毁。只有在最后析构函数中才被销毁。
看来 使用char存储字符不是很方便,比如要执行字符串拼接等操作,可能还是需要string类型更好。



