这块内容还是非常关键的,因为涉及到了设计模式中的概念:接口。
纯虚函数
纯虚函数的语法规则:
(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,因为它是被设计用于继承的。