完全不知道怎么取标题,但是不进来看看也许会后悔--其实我一开始想写关于virtual 函数的

Posted 小键233

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了完全不知道怎么取标题,但是不进来看看也许会后悔--其实我一开始想写关于virtual 函数的相关的知识,希望对你有一定的参考价值。

假如,现在有个类,它含有数据,我们需要为它编写一些遍历的函数。
就比如,类是这样的:

class SomeClass

    enum Length = 512;
    int element[Length];
public:
    void traver()
    
        //做一些遍历
    
;

那如果有需求,要求遍历函数能够依据不同的情况,采取不同的遍历函数,怎么办呢?
可以让SomeClass 包含一个函数指针,通过函数指针调用函数进行遍历,还可以通过修改函数指针的值,以产生不同的遍历行为。
这个代码就不写了。但是这样有个明显的问题,如果我在函数中,还需要额外的参数呢?那怎么办?

我们可以额外声明一个抽象类,提供接口用于编写遍历函数

class DoFunc

public:
    virtual ~DoFunc() 
    virtual void func(int&) = 0;
;

class Increase: public DoFunc

public:
    void func(int& i)
    
        ++i;
    
;

class Decrease: public DoFunc

public:
    void func(int& i)
    
        --i;
    
;

class SomeClass

    enum Length = 512;
    int element[Length];
    DoFunc* dofunc;


public:
    SomeClass(DoFunc* indo): dofunc(indo) 
    void traver()
    
        for(int i=0;i<Length;++i)
            dofunc->func(element[i]);
    
    void setFunc(DoFunc* indo)
    
        dofunc = indo;
    
;

那么,对于使用这样:

    Increase in;
    Decrease de;
    SomeClass s(&in);
    //...
    s.setFunc(&de);

这是一种不错的设计方案:

至于参数,只要让DoFunc 的derived class 拥有就可以了。

除此之外,我们还可以使用模板

class Increase

public:
    void operator () (int& i)
    
        ++i;
    
;

class Decrease

public:
    void operator () (int& i)
    
        --i;
    
;

class SomeClass

    enum Length = 512;
    int element[Length];
public:
    SomeClass()
    template<typename T>
    void traver(T t)
    
        for(int i=0;i<Length;++i)
            t(element[i]);
    
;

模板能够接受的参数很多,函数指针,重载了() 操作符的类,lambda 表达式等。
那么使用可以如下:

    Increase in;
    Decrease de;
    SomeClass s;
    s.traver(in);
    s.traver(de);
    s.traver([](int& i) -> void 
    
        i += 10;
    );

[参考资料]
[1] Scott Meyers 著, 侯捷译. Effective C++ 中文版: 改善程序技术与设计思维的 55 个有效做法[M]. 电子工业出版社, 2011.
(条款35:考虑virtual 函数以外的选择)

以上是关于完全不知道怎么取标题,但是不进来看看也许会后悔--其实我一开始想写关于virtual 函数的的主要内容,如果未能解决你的问题,请参考以下文章

Html加载已经完全下载,但是网页只显示了一半内容,怎么半?

PHP之在朗沃最后一段感想

1回顾大学四年,后悔没有这样做

1回顾大学四年,后悔没有这样做

重新认识java ---- 面向对象之多态(向上转型与向下转型)

转面向对象之多态(向上转型与向下转型)