什么是纯虚函数?
纯虚函数也是虚函数(特殊的虚函数)
????????纯虚函数没有函数体
? ? ? ? 只能在类中函数这样写,把这样的函数叫纯虚函数
virtual void print()= 0;//在类中函数 这样写法 或者 原来的虚函数不想写函数体直接=0就是纯虚函数
本质就是重写过程?--- 用了别人的框架,别人把具体功能实现了,想要改变某些属性就需要重写
例:mfc中创建窗口的过程父类中已经写好了,但是创建的窗口是默认窗口大小,作为用户可能不需要默认大小,想修改宽高--->提供了一个纯虚函数instance用来初始化数据,重写这个函数,在这个函数中设置窗口的属性
什么是抽象类?
抽象类: 具有至少一个纯虚函数的类,叫做抽象类
抽象类不能在类中声明在类外实现
//抽象类
class Parent
{
public:
virtual void print();
protected:
};
void Parent::print()=0; //错误
?抽象类不能构建对象,可以构建对象指针
//抽象类
class Parent
{
public:
virtual void print()= 0; //纯虚函数 无函数体
protected:
};
void testAbstract()
{
//Parent object; 抽象类不能构建对象
Parent* parent = nullptr; //但是能够构建指针
}
模拟一个栈的实现过程
-
入栈、出栈 -
获取栈元素 -
判断栈是否为空 -
获取栈的大小
/* 纯虚函数就是做ADT(abstract data type 抽象数据类型) 过程 */
做好的框架,测试代码写好了,剩下实现功能的代码让别人去实现
//stack 栈
class stack
{
public:
//抽象一个类,已经知道栈的基本操作,父类中所有的操作描述好
virtual void push(int data) = 0;
virtual void pop() = 0;
virtual int top() const = 0;
virtual bool empty() const = 0;
virtual int size() const = 0;
};
//子类想要创建对象,必须重写父类的纯虚函数
//ADT: 具有强迫性,所有子类重写函数必须和父类的一模一样(函数体不一样),如果不一样会报错
class arrayStack :public stack //数组栈---用数组实现一个栈
{
public:
void push(int data) //入栈---入一个整数
{
}
void pop() //出栈
{
}
int top() const //获取栈最上面的元素
{
return 1;
}
bool empty() const //判断是否为空
{
return true;
}
int size() const //获取大小
{
return 1;
}
//可以增加别的函数---但是纯虚函数必须要写
//可以增加别的数据成员
protected:
int* array; //数组栈---需要数组的指针
};
struct Node //节点---用链表实现,需要结构体
{
int data;
Node* next;
};
//不管做什么栈,重写抽象类即可
class listStack :public stack //链式栈---用链表实现一个栈
{
public:
void push(int data)
{
}
void pop()
{
}
int top() const
{
return 1;
}
bool empty() const
{
return true;
}
int size() const
{
return 1;
}
protected:
Node* headNode; //表头
};
void testStack(stack* pStack) //测试代码---传入抽象类的指针
{
pStack->push(1); //入栈,入1
while (!pStack->empty()) //判断栈是否为空
{
cout << pStack->top(); //如果不为空,获取栈的元素后,不断出栈
pStack->pop();
}
}
int main()
{
//用方法调用,测试代码是一样的---和统一接口差不多
testStack(new arrayStack);
testStack(new listStack);
Abtract();
return 0;
}
?小知识:
如果没有实现纯虚函数,这个类永远都是抽象类,一般情况下,抽象类只被继承一次,因为一个类被继承多次后可能忘记哪个函数是纯虚函数
class A
{
public:
virtual void print() = 0; //纯虚函数
protected:
};
class B :public A //A类继承产生B类,B类还是抽象类
{
public:
};
class C :public B //B类再产生一个类,C类也是抽象类
{
public:
};
void Abtract()
{
//B b; B类没有重写不能构造对象
}
重写B类后,C类能构建对象
class A
{
public:
virtual void print() = 0; //纯虚函数
protected:
};
class B :public A
{
public:
void print()
{
cout << "B" << endl;
}
};
class C :public B
{
public:
};
void Abtract()
{
B b; //B类重写后能构造对象
C c;
}
纯虚函数也是虚函数的一种
在实现多态的时候,不需要virtual修饰
class A
{
public:
virtual void print() = 0; //纯虚函数
protected:
};
class B :public A
{
public:
void print()
{
cout << "B" << endl;
}
};
class C :public B
{
public:
void print()
{
cout << "C" << endl;
}
};
void Abtract()
{
//B b;
C c; //一般抽象类只被继承一次就重写
B* pb = new C; //父类指针用子类对象初始化
pb->print(); //虚函数无论被继承多少次,都是虚函数,有无virtual,都存在一个虚函数
}
int main()
{
Abtract(); /*输出:C 子类对象初始化父类指针有virtual看对象类型,没有virutal
看指针类型,这里看的是对象类型*/
return 0;
}
|