前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >创建通用函数对象的三种方法

创建通用函数对象的三种方法

作者头像
用户9831583
发布2022-06-16 16:57:45
4910
发布2022-06-16 16:57:45
举报
文章被收录于专栏:码出名企路

题目:创建一个函数对象,检查一个人、一辆汽车或一条狗的年龄大于限定值的个数。

此对象,我们定义为 older_than,这是一个类对象。

方法一:面向对象

创建一个包含 age()虚函数的超类。

代码语言:javascript
复制
class Object  
{  
    public:  
        virtual int age() = 0;  
};  
class A:public Object  
{  
    public:  
        int age(){return 21;}  
};  
class B:public Object  
{  
    public:  
        int age(){return 11;}  
};  
class older_than  
{
    public:  
        bool operator()(Object* object){  
            return object->age() > m_limit;  
        }  
    private:  
        int m_limit = 12;  

};  
std::count_if(persons.cbegin(), persons.cend(), older_than(new A()));  
std::count_if(cars.cbegin(), cars.cend(), older_than(new B()));

但是:这种方法会影响运行时的性能,而且对与支持 older_than函数对象的所有类都必须强制继承这个超类,破坏了封装性。

方法二:类模板

将 older_than类改造成类模板,对于需要检测年龄的类型创建模板类。

代码语言:javascript
复制
template<typename T>  
class older_than  
{  
    public:  
        older_than(int limit):m_limit(limit){}  
        bool operator()(const T& object) const{  
            return object.age() > m_limit;  
        }  
    private:  
        int m_limit;  
};  
//对于具有 .age() get方法的任意类型都可以使用 older_than  
std::count_if(persons.cbegin(), persons.cend(), older_than<person_t>(42));  
std::count_if(cars.cbegin(), cars.cend(), older_than<cars_t>(42));  
std::count_if(dogs.cbegin(), dogs.cend(), older_than<dogs_t>(42));  

但是:这种方法在实例化的时候要检测对象,必须指定对象的类型,很可能导致指定的类型与调用操作符要求的类型不一致的问题。

方法三:模板成员函数

因此,可以把调用操作符合作为一个模板成员函数,而不是创建一个模板,这种情况在实例化 older_than函数对象时,就不需要指定类型,编译器在调用“调用操作符”时,会自动推测参数的类型。

代码语言:javascript
复制
template<typename T>  
class older_than  
{  
    public:  
        older_than(int limit):m_limit(limit){}  
        template<typename T>  
        bool operator()( T&& object) const{  
            //age成员函数有不同的重载 左值和右值,可调用正确重载  
            return std::forward<T>(object).age() > m_limit;  
        }  
    private:  
        int m_limit;  

};  
//再使用 older_than函数对象时,就不用显式指明对象类型了,甚至可以对不同的类型使用相同的对象示例  
older_than pp(5);  
std::count_if(persons.cbegin(), persons.cend(), pp);  
std::count_if(cars.cbegin(), cars.cend(), pp);  
std::count_if(dogs.cbegin(), dogs.cend(), pp);  

认识一个人就是开了一扇窗户,就能看到不一样的东西,听到不一样的声音,能让你思考,觉悟,这已经够了。其他还有很多,比如机会,帮助,我不确定。这个在一般人看来可能不重要,但是我知道这个很重要。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码出名企路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档