【C++】纯虚函数和抽象类(virtual)

这块内容还是非常关键的,因为涉及到了设计模式中的概念:接口。

纯虚函数

纯虚函数的语法规则:

(1)将成员函数声明为virtual;

(2)后面加上=0;

(3)该函数没有函数体。

class CmdHandler
{
public:
	virtual void OnCommand(char* cmdline) = 0;
};

含有纯虚函数的类,称为抽象类(或者纯虚类)。抽象类不能被实例化,即无法创建该对象。

CmdHandler ch; //编译错误

CmdHandler* p = new CmdHandler(); //编译错误

不能被实例化,那这个类有什么用?

抽象类(纯虚函数)的实际用途,充当“接口规范”。用于替代C中的回调函数的用法。

接口规范,凡是遵循此规范的类,都必须实现指定的函数接口,通常是一系列接口。

比如上面那个CmdHandler类,只要用到这个类了,那就必须实现OnCommand这个函数。 

程序功能:用户输入一行命令,按回车完成输入。要求解析命令输入,并且处理。

设计:CmdInput:用于接收用户输入

           CmdHandler:规定一系列函数接口

           MyParser:接口的实现,实际用于解析处理的类

CmdHandler.h文件

#pragma once
#ifndef _CMDHANDLER_H
#define _CMDHANDLER_H


class CmdHandler
{
public:
	virtual ~CmdHandler() {};
	virtual void OnCommand(char* cmdline) = 0;
};

#endif

CmdInput.h文件

#pragma once
#ifndef _CMDINPUT_H
#define _CMDINPUT_H

#include "CmdHandler.h"

class CmdInput
{
public:
	CmdInput();
	void SetHandler(CmdHandler* h);

	int Run();

private:
	CmdHandler* m_handler;
};

#endif

CmdInput.cpp文件

#include "pch.h"
#include "CmdInput.h"
#include "stdio.h"
#include "string.h"

CmdInput::CmdInput()
{
	m_handler = NULL;
}


void CmdInput::SetHandler(CmdHandler* h)
{
	m_handler = h;
}

int CmdInput::Run()
{
	char cmdline[256];
	while (1)
	{
		printf("> ");
		gets_s(cmdline);
		if (strcmp(cmdline, "exit") == 0)
		{
			break;
		}

		if (m_handler)
		{
			m_handler->OnCommand(cmdline);
		}
	}
	return 0;
}

MyParser.h文件

#pragma once
#ifndef _MYPARSER_H
#define _MYPARSER_H

#include "CmdHandler.h"

class MyParser : public CmdHandler
{
public:
	MyParser();
public:
	virtual void OnCommand(char* cmdline);
private:
	int Split(char text[], char* parts[]);
};

#endif

MyParser.cpp文件

#include "pch.h"
#include "MyParser.h"
#include "stdio.h"

MyParser::MyParser()
{}

void MyParser::OnCommand(char* cmdline)
{
	char* argv[128];
	int argc = Split(cmdline, argv);

	if (argc > 0)
	{
		printf("命令:%s \n", argv[0]);
		printf("参数:");

		for (int i=1; i<argc; i++)
		{
			printf("%s ", argv[i]);
		}
		printf("\n\n");
	}
}

int MyParser::Split(char text[], char* parts[])
{
	int count = 0; //分段的个数
	int start = 0; //每一分段的首地址
	int flag = 0; //遍历text,标识当前是否处于有效字符

	int stop = 0; //是否到达结束
	for (int i = 0; !stop; i++)
	{
		char ch = text[i];
		if (ch == 0)
		{
			stop = 1; //停止循环
		}

		if (ch == ',' || ch == '\0' || ch == ' ' || ch == '\t')
		{
			if (flag)
			{
				flag = 0;
				text[i] = 0;
				parts[count] = text + start;
				count++;
			}
		}
		else
		{
			if (!flag)
			{
				flag = 1;
				start = i;
			}
		}
	}

	return count;
}

main.cpp文件

#include "pch.h"
#include <iostream>
#include "string.h"
#include "CmdInput.h"
#include "MyParser.h"

int main()
{
	CmdInput input;
	MyParser parser;

	input.SetHandler(&parser);
	input.Run();

	return 0;
}

注意:

(1)抽象类的析构函数应该声明为virtual,因为它是被设计用于继承的。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值