利用解释器模式模拟音乐播放 C++

1. 解释器模式

解释器模式, 就是给定一个语言, 定义他的文法的一种表示, 并定义一个解释器, 这个解释器使用该表示来解释语言中的句子。
如果一种特定类型的问题发生的频率足够高, 那么可能就值得将该问题的各个实例表述为一个简单语言中的一个句子。 这样就可以构建一个解释器, 该解释器通过解释这些句子来解决该问题。
正则表达式就是他的一种应用。
直观上就感觉是带了一个翻译一样。
他可以很容易的改变和扩展文法, 因为该模式使用类来表示文法规则, 你可以使用继承来改变或者扩展文法。 同时文法也是比较容易实现的, 因为定义抽象语法树中的各个节点的类的实现是大体类似的, 都易于直接编写。

2. UML

这里写图片描述

3. 运行效果

这里写图片描述

4. code

playcontext.h

#ifndef _PLAYCONTEXT_H_
#define _PLAYCONTEXT_H_

#include <string>
using std::string;

class PlayContext{
public:
    string Text() const { return text; }
    void Text(string val) { text = val; }

private:
    string text;
};

#endif //_PLAYCONTEXT_H_

expression.h

#ifndef _EXPRESSION_H_
#define _EXPRESSION_H_

#include "playcontext.h"
#include <string>
#include <sstream>

using std::string;
using std::istringstream;
using std::to_string;

class Expression{
public:
    void Interpret(PlayContext * context){
        string playKey;
        double playValue;
        if (context->Text().size() == 0)
            return;
        else{
            string tmp = context->Text();
            istringstream istr(tmp);
            istr >> playKey >> playValue;
            string test;
            getline(istr, test);
            context->Text(test);
        }

        Excute(playKey, playValue);
    }

    virtual void Excute(string key, double value) = 0;
};


#endif // _EXPRESSION_H_

mainexpression.h

#ifndef _MAINEXPRESSION_H_
#define _MAINEXPRESSION_H_

#include "expression.h"
#include <string>
#include <iostream>

using std::string;
using std::cout;

class Note : public Expression{
public:
    void Excute(string key, double value) override{
        string note = "";

        if (key == "C")
            note = "1";
        else if (key == "D")
            note = "2";
        else if (key == "E")
            note = "3";
        else if (key == "F")
            note = "4";
        else if (key == "G")
            note = "5";
        else if (key == "A")
            note = "6";
        else if (key == "B")
            note = "7";

        cout << note << " ";
    }
};

class Scale : public Expression{

    void Excute(string key, double value){
        string scale = "";
        switch (int(value))
        {
            case 1:
                scale = "低音";
                break;
            case 2:
                scale = "中音";
                break;
            case 3:
                scale = "高音";
                break;
            default:
                break;
        }
        cout << scale << " ";
    }   
};


#endif // _MAINEXPRESSION_H_

main.cpp

#include "mainexpression.h"
#include "playcontext.h"

#include <iostream>
using namespace std;

int main(){
    PlayContext * context = new PlayContext();
    cout << "上海滩: " << endl;
    context->Text(" O 2 E 0.5 G 0.5 A 3 E 0.5 G 0.5 D 3 E 0.5 G 0.5 A 0.5 O 3 C 1 O 2 A 0.5 G 1 C 0.5 E 0.5 D 3");
    Expression * expression = nullptr;
    while (context->Text().size() > 0){
        string str = context->Text().substr(0, 1);
        if (str == "O")
            expression = new Scale();
        else
            expression = new Note();

        expression->Interpret(context);
    }

    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值