c++纯虚函数(特殊的虚函数)和ADT过程(抽象数据类型)

什么是纯虚函数?

  • 纯虚函数也是虚函数(特殊的虚函数)

  • 只是纯虚函数是没有函数体的

  • 本质就是重写过程→用了别人的框架,别人把具体功能实现了,想要改变某些属性就需要重写

  • 纯虚函数一般写为公有属性(要实现多态),如果只在类中调用,可以写为保护属性

//原来的虚函数不写函数体直接=0就是纯虚函数  在类中函数这样写 
virtual void print()= 0;

用到别人的框架需要重写别人的方法:mfc中创建窗口的过程,父类中已经写好了,但是创建的窗口是默认窗口大小,作为用户可能不需要默认大小,想修改宽高--->提供了一个纯虚函数Instance用来初始化数据,重写这个函数,在这个函数中设置窗口的属性

什么是抽象类?

具有至少一个纯虚函数的类,叫做抽象类

  • 抽象类不能构建对象

  • 抽象类可以构建对象指针

  • 抽象类不能在[类中声明,在类外实现]

抽象类不能在类中声明在类外实现

//抽象类
class Parent 
{
public:
	virtual void print();  	
protected:
};
void Parent::print()=0;   //报错:纯虚函数不能在类中声明,类外实现
//不能在成员函数"Parent::print"的类外部重新声明该函数

抽象类不能构建对象,可以构建对象指针

//抽象类
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;
};
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);
	return 0;
}

 小知识:

  • 子类想要创建对象,必须重写父类的纯虚函数 

  • ADT:具有强迫性,所有子类重写函数必须和父类的一模一样(函数体可以不一样),如果不一样会报错

  • 如果子类如果没有实现父类的方法,还是抽象类,不能构建对象,我们只能去实现一下这些功能,让它可以构建对象

  • 可以增加别的函数&数据成员,但是父类中的抽象必须要重写

  • ADT就是虚函数和多态的使用,只是用的是纯虚函数而已

  • 纯虚函数如果没有被重写,无论继承多少次都是纯虚函数,虚函数无论被继承多少次都是虚函数

无论被继承多少次,如果没有实现纯虚函数,这个类永远都是抽象类,一般情况下,抽象类只被继承一次就重写,因为一个类被继承多次后可能忘记哪个函数是纯虚函数

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|C类没有重写不能构建对象
	//C c;    C也是抽象类
}

重写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() 
{
	C c;          
	B* pb = new C; //子类对象初始化父类指针
	pb->print();   //虚函数无论被继承多少次一直都是虚函数,有无virtual,都存在一个虚函数
                    
}
int main() 
{
//下面实现多态,不需要virtual
	Abtract();     /*输出:c  子类对象初始化父类指针没有virutal看指针类型,有
                             virtual看对象类型,这里是看对象类型:C的类型*/
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiuqiuyaq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值