trustwood第三章:实现一个简单的selector类

 特别地,今天不讲P话,我们直接开始。

selector是什么呢,是函数映射,Java之类的编程语言是自带的,但是C++是没有的,所以我们便可以用C++自带的函数指针来实现

typedef const void* SEL;
SEL NSSelectorFromString(const std::string& str) {
    static std::mutex mutex;
    static std::set<std::string> selectorStrings;
    std::lock_guard<std::mutex> lock(mutex);
    auto it = selectorStrings.find(str);
    if (it != selectorStrings.end()) {
        return reinterpret_cast<SEL>(&(*it));
    } else {
        auto result = selectorStrings.insert(str);
        return reinterpret_cast<SEL>(&(*result.first));
    }
}

给出一段代码。这一段代码首先定义了一种新的静态指针类型SEL,并且通过字符串的加入或查找返回SEL对象。加了个锁,可以保证使用时的线程及数据安全。

class Function {
public:
    
    void print(std::vector<std::string> t) {
        for (auto& i : t)
            cout << i << " ";
        cout << "\n";
    }
    
    void print() {
        cout << " \n";
    }

    void perform(SEL selector, const std::vector<std::string>& args = {}) {
        static const auto& handlerMap = getHandlerMap();
        auto it = handlerMap.find(selector);
        if (it != handlerMap.end()) {
            it->second(this, args);
        } else {
            std::cerr << "Unrecognized selector" << std::endl;
        }
    }
    
private:
    using Handler = std::function<void(Function*, const std::vector<std::string>&)>;
    static const std::map<SEL, Handler>& getHandlerMap() {
        static const std::map<SEL, Handler> handlerMap = {
            { NSSelectorFromString("print"),
                [](Function* obj, const auto& args) { obj->print(); }},
            
            { NSSelectorFromString("printWithVector"),
                [](Function* obj, const auto& args) { obj->print(args); }}
        };
        return handlerMap;
    }
};

这一段代码则是实现了核心功能,定义了一个function类,首先定义了两个print函数,可以处理空或有参数的情况,如果空则输出空加换行,否则就输出要输出的参数。perform是function类最核心的内容,它处理了函数映射,在私有的getHandlerMap里面找寻要perform的SEL对象,当然getHandlerMap的实现是通过定义一个有Function类的指针与输出内容参数的Handler函数封装类型(我们一般在其他语言中称作闭包,你们可以理解为被储存起来的函数),然后定义一个静态的map,将Function类中的print和printWithVector字符串函数名转为SEL对象作为键,便于来储存调用对应函数的Handler对象。

selector(函数映射)实现对于编程语言对于函数调用处理时是很有意义的 

好了,那我们如何来调用呢,比如以下代码

print("A")

我们可以拆成

{"print", "(", "\"A\"", ")"}

我们很容易发现,参数是"\"A\"",而我们调用一般去掉开头和结尾的"\"",由于有参数我们应调用printWithVector

以下是上述代码的调用代码

auto fun = Function();
auto actionStr = "printWithVector";
auto sel = NSSelectorFromString(actionStr);
fun.perform(sel, {"A"});

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值