条款二十五:将constructer和nonmember function虚化

原创 2016年08月30日 16:11:36

条款二十五:将constructer和nonmember function虚化

1. 虚化构造函数

  当看到将构造函数虚化时你可能想到C++语法不是只支持析构函数的虚化而不允许构造函数的虚化吗?其实这里说的是将构造函数虚化,不是构建虚构造函数。我们可以想象一个场景,我们开发了一个处理服务器的软件,内容为文字,图片,视频等我们将程序中这些数据的管理设计为下面的代码:

    class data_object
    {
    public:
        virtual void operate() = 0;
    };

    class text:public data_object
    {
    public:
        virtual void operate();
    }

    class photo:public data_object
    {
    public:
        virtual void operate();
    };

    class data_manager
    {
    private:
        std::list<data_object*> _data_list;
    }

  而数据储存在服务器的磁盘上我们需要通过从磁盘上读取数据可能代码如下:

    class data_manager
    {
    private:
        std::list<data_object*> _data_list;
    public:
        data_manager(istream& str)
        {
            while(1)
            {
                //TODO:read data from disk and insert into list
            }
        }
    };

  如果我们将数据的读取交由一个函数去做,代码就会变成:

    class data_manager
    {
    private:
        std::list<data_object*> _data_list;
    public:
        static data_object* read_data(istream& str);
        data_manager(istream& str)
        {
            while(1)
            {
                //TODO:read data from disk and insert into list
                _data_list.push_back(read_data(str));
            }
         }
     };

  read_data函数的作用就是根据从磁盘输入的数据类型生成对应的类的类型,这就是一个虚构造函数尽管他不是虚函数但是完成了虚函数可以完成的功能。在这里构造函数将自己无法完成的功能外包出给成员函数,就如同现实生活中的外包公司一般完成一些额外的任务。
  另一中虚构造函数就是虚拷贝构造函数,徐拷贝构造函数会返回一个自身的指针,指向自身的一个副本,代码如下:

    class object
    {
    public:
        virtual object* clone() const = 0;
    }

    class dialog:public object
    {
    public:
        virtual dialog* clone() const
        {
            return new dialog(*this);
        }
    }

    class widget:public object
    {
    public:
        virtual widget* clone() const
        {
            return new widget(*this);
        }
    }

  从代码中可以看到虚拷贝构造函数其实就是调用了一个拷贝构造函数而已,他的行为取决于类的拷贝构造函数,如果在环境中只是进行简单的浅拷贝,那么clone的行为会紧跟拷贝构造函数,如果需要深拷贝clone的行为亦然。也就是说保留这之前我们谈到过的缓时评估。
  上述虚拷贝构造函数能够成功的原因是C++中允许继承类也就是子类重新定义基类也就是父类中的虚函数时使用与父类不同的返回值,但是返回值必须存在继承关系,如果两个虚函数的返回值一个是int另一个是void就会编译错误!

2. 虚化无成员函数(non-member function)

  对于无成员函数的虚化可以让无成员函数也拥有多态的性质,但是如果仅仅是按照一般的函数设计就会出现一些不方便的地方比如,根据类的类型重载<<操作符:

    class father
    {
    public:
        virtual ostream& operator<<(ostream& os) const
        {
            os<<"father out!\n";
            return os;
        }
    };

    class son:public father
    {
    public:
        virtual ostream& operator<<(ostream& os) const
        {
            os<<"son out!\n";
            return os;
        }
    };

  上述代码可以实现对应的功能但是调用方式就不是那么的方便了。必须按照以下方式调用:

    father fh;
    son    s;
    s<<cout;
    fh<<sout;

  这明显和我们习惯的调用方式有所差距。另一中简单的办法是将打印的功能封装为一个成员函数让这个操作符重载函数调用这个封装的函数比如

    #include<iostream>
    using namespace std;

    class object
    {
    public:
        virtual ostream& print(ostream& os) const = 0;
    };

    class dialog:public object
    {
    public:
        virtual ostream& print(ostream& os) const
        {
            std::cout<<"dialog run!\n";
        }
    };

    class widget:public object
    {
    public:
        virtual ostream& print(ostream& os) const
        {
            std::cout<<"widget run!\n";
        }
    };

    inline ostream& operator<<(ostream& os,const object& ob)
    {
        return ob.print(os);
    }

    int main(int arg,char* ar[])
    {
        dialog dlg;
        widget w;

        cout<<dlg;
        cout<<w;

        return 0;
    }

  代码中将打印工作封装再由重载操作调用完成更好的包装。

版权声明:本文为博主原创文章,未经博主允许不得转载。

照片处理:PS三步轻松实现背景虚化

在摄影实践中,虚化背景是突出主体的常用手段。但是由于消费级DC镜头的实际焦距都很短,因此实现浅景深而虚化背景的难度较大。如果我们希望用消费级DC也能达到虚化背景突出主体的效果,那么,Photoshop...
  • sven_xu
  • sven_xu
  • 2015年06月02日 09:18
  • 605

图像处理之背景虚化

废话不多说,先上图。 原图 圆形的清晰区域 水平的清晰区域 竖直的清晰区域 嘿嘿,看上去还可以哈~~我们这里说的背景虚化呢,自然没有能力做到自动识别背景与前景的,所以只能算是一个半自动...
  • xiayang1023
  • xiayang1023
  • 2014年11月30日 20:35
  • 1523

Android 图片虚化,虚化图片,模糊图片

Blur 自从iOS系统引入了Blur效果,也就是所谓的毛玻璃、模糊化效果,磨砂效果,各大系统就开始竞相模仿,这是一个怎样的效果呢,我们现来看一些图: 这些就是典型的Blur效果,...
  • HarryWeasley
  • HarryWeasley
  • 2015年12月10日 20:21
  • 3292

App Store审核条款(2016.06.21更新)

App Store 审核条款
  • bb1223
  • bb1223
  • 2016年06月21日 14:33
  • 1707

图像算法研究---背景虚化算法

本文在抠图算法基础上,实现了一种如何实现单反背景虚化效果的算法,更具单反的真实感,跟大家分享一下!...
  • Trent1985
  • Trent1985
  • 2017年07月24日 20:18
  • 5471

Android 虚化图片的方法

Android 虚化图片 模糊图片 图片毛玻璃效果。 效果如图: 在Android可以用RenderScript方便的实现这个方法: private void blur(Bitmap b...
  • h3c4lenovo
  • h3c4lenovo
  • 2014年06月02日 18:21
  • 16034

【Android开发】范例3-"我同意"游戏条款

实现游戏开始界面中的我同意游戏条款功能:不勾选“我同意”复选框,就不会出现“开始游戏”的按钮,勾选“我同意”复选框,出现“开始游戏”的按钮。 效果图如图: 未点击"我同意"之前 点击“我同意”之...
  • u013517797
  • u013517797
  • 2015年04月03日 09:54
  • 1248

《Effective C++》学习笔记——条款25

《Effective C++》学习笔记——条款25:考虑写出一个不抛异常的 swap 函数
  • lx417147512
  • lx417147512
  • 2014年12月30日 22:32
  • 835

图片虚化处理

最近在某些app 上面看到banner 图 的图片虚化,然后花了一点时间去处理了这个问题 #import "ViewController.h" ...
  • jq2530469200
  • jq2530469200
  • 2016年08月03日 11:03
  • 264

图像背景虚化

在一幅摄影作品中,背景虚化可以很好地烘托主体,但是对于一些摄影爱好者来说,大光圈太贵;长焦镜头使用时限制太多;手中相机功能太低……虽条件不足,但又很想拍出主体突出、背景虚化的照片,这时候该怎么办呢?...
  • bluecol
  • bluecol
  • 2015年05月04日 15:10
  • 2796
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:条款二十五:将constructer和nonmember function虚化
举报原因:
原因补充:

(最多只允许输入30个字)