第一招虚函数

通过派生类来进行功能扩展是基本的面向对象的方式,这种方式大如下:

class base

{

public:

virtual ~base(){}

virtual void fun()

{

cout << "基本功能" << endl;

}

};

class derive:public base

{

public:

void fun()

{

cout << "扩展功能" << endl;

}

};

这种方式下,基类通过声明虚函数,让派生类来覆盖,最后通过多态来实现扩展功能。这种方式的最大的缺点是基类的编写者一般很难确定虚函数的功能究竟要实现到什么程度,如果有一天突然发现一个虚函数的功能要进行扩张(或收缩),那么所有从这个基类派生的类都要进行编译。这种方式的另一个缺憾是。功能的扩展不能在运行时设定。

第二招组合

通过组合方式来为类的功能扩展留下余地的方式,要比通过继承的方式在耦合方面要松的多。就是把上面的虚函数所要委托给一个其它的类。这种方式大体如下:

class action

{

public:

virtual void fun()

{

cout << "基本功能" << endl;

}

};

class exAction:public action

{

public:

virtual void fun()

{

cout << "扩展功能" << endl;

}

};

class app

{

public:

app():paction(NULL){}

virtual ~app(){}

virtual void fun()

{

if(paction)

paction->fun();

}

void setActoin( action* action_)

{

paction = action_;

}

private:

action* paction;

};

在这个例子中,类app把它的功能委托给了类action。这样一来,类app就和它的功能进行了解藕。解藕后的类app现在可以在运行时进行功能设定了。通过组合的方式虽然解藕了也能进行功能的运行时设定了。但却明显地不如第一种方式效率高。

第三招函数指针成员

通过函数指针成员方式,可以提高效率。这种方式大体如下:

class app

{

public:

app():pfun(NULL){}

virtual ~app(){}

typedef void(*FUN)();

void setFun(FUN fun_)

{

pfun = fun_;

}

virtual void fun()

{

if( pfun)

pfun();

}

private:

FUN pfun;

};

第四招成员模板函数

通过为类预留一个成员模板函数,而为类的使用者留下扩展的余地。这种方式简捷、干练。遗憾的是这种方式不能用在动态方面上。这种方式大体如下:

class app

{

public:

app(){}

virtual ~app(){}

template <class T>

void fun( T& t_)

{

cout << "基本功能" << endl;

}

};

template < >

void app::fun(int & t_)

{

cout << "扩展功能" << endl;

}

这种方式还能依偏特化的形式进行,具体请参考我的另一篇blog《让后门能够偏特化》。使用这种方式最奇妙的是声明一个模板构造函数来扩展类的构造功能。

第五招模板基类

上面的几种方式都是针对一个要进行开发的类为这个要开发的类留下扩展余地。那么能不能让要开发的类用来扩展任意的已开发好的类的功能呢?这就是第五招模板基类。这种方式大体如下:

template < class T>

class exApp:public T

{

public:

void fun()

{

cout << "扩展功能" << endl;

}

};

现在我们可以方便的把类exApp的功能添加到任意的其它的类上了。这种扩展方式的功能非常强悍,它甚至引出一个专门的编程方式:“基于策略的编程”。

详见《C++程序设计就思维》。

原文转自:http://blog.csdn.net/guanwl/article/details/2358073

原作者为 guanwl。请尊重原作者版权

C++类功能扩展预留五招的更多相关文章

  1. 利用Mixins扩展类功能

    8.18 利用Mixins扩展类功能 - python3-cookbook 3.0.0 文档 https://python3-cookbook.readthedocs.io/zh_CN/latest/ ...

  2. [转]用GSON 五招之内搞定任何JSON数组

    关于GSON的入门级使用,这里就不提了,如有需要可以看这篇博文 <Google Gson的使用方法,实现Json结构的相互转换> ,写的很好,通俗易懂. 我为什么写这篇文章呢?因为前几晚跟 ...

  3. [转] Android:用GSON 五招之内搞定任何JSON数组

    [From] http://www.open-open.com/lib/view/open1472632967912.html 写在前面 关于GSON的入门级使用,这里就不提了,如有需要可以看这篇博文 ...

  4. 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...

  5. WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展

    一.前言.预览 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要是对文本 ...

  6. IOS基础之 (十二) 类的扩展

    对OC类的扩展总结如下,共有4个: 1.子类 subClass 作用:可以使用类的继承来增添父类的变量和方法. 写法:在.h文件中 @interface Student : Person 2.分类 C ...

  7. spring源码深度解析-2功能扩展

    容器功能的扩展ApplicationContext用于扩展BeanFactory中现有的功能.究竟多出了哪些功能,进一步探索.写法上:BeanFactory bf = new XmlBeanFacto ...

  8. vs.net 2013 Saffolding功能扩展

    vs.net 2013 Saffolding功能扩展 Asp.net mvc 5 CRUD代码自动生成工具 -Visual Studio.net2013 Saffolding功能扩展 上次做过一个&l ...

  9. Asp.net mvc 5 CRUD代码自动生成工具- vs.net 2013 Saffolding功能扩展

    Asp.net mvc 5 CRUD代码自动生成工具 -Visual Studio.net2013 Saffolding功能扩展 上次做过一个<Asp.net webform scaffoldi ...

随机推荐

  1. LLVM 笔记(一)—— phi 指令

    ilocker:关注 Android 安全(新手) QQ: 2597294287 语法: <result> = phi <ty> [ <val0>, <lab ...

  2. [引] Security tips for web developers

    Source :Security tips for web developers

  3. plain framework 1 参考手册 入门指引之 简明教程

    简明教程 简单的例子 实现代码 简单的例子 如果你已经下载好整个框架的源码,那么你可以在这里找到应用的例子: plainframework/applications/pf_simple 如果你在win ...

  4. voxel 与 pixel

    中文名称:体素,即顾名思义是体积的像素.用来在三维空间中表示一个显示基本点的单位.类似于二维平面下的pixel(像素). voxel是三维空间中定义一个点的图象信息的单位.在平面中定义一个点要两个坐标 ...

  5. 利用T-Sql语句中的二重循环打印乘法口诀表

    --定义三个初始化变量 declare @a int,@b int,@c varchar(200) --对@a进行赋值 set @a=1 --循环输出9次,@a为被乘数 while(@a<=9) ...

  6. 深入Java核心 Java内存分配原理精讲

    深入Java核心 Java内存分配原理精讲 栈.堆.常量池虽同属Java内存分配时操作的区域,但其适用范围和功用却大不相同.本文将深入Java核心,详细讲解Java内存分配方面的知识. Java内存分 ...

  7. 从零开始学CSRF

    为什么要拿CSRF来当"攻击手法系列"的开头篇呢?因为CSRF/XSRF我个人喜爱他的程度已经超过XSS了.如果说XSS是一个老虎,那么CSRF就是隐藏在暗处的蛇. 相信现在很多人 ...

  8. jquery工具方法makeArray/merge

    makeArray : 类数组转真数组 merge : 合并数组或转特殊json 使用例子(外部使用): var aDiv = document.getElementsByTagName('div') ...

  9. linux运维中的命令梳理(四)

    ----------管理命令---------- ps命令:查看进程 要对系统中进程进行监测控制,查看状态,内存,CPU的使用情况,使用命令:/bin/ps (1) ps :是显示瞬间进程的状态,并不 ...

  10. C语言:关于socket的基础知识点

    /** * ---结构体--- * * #include <sys/socket.h> * struct sockaddr { * unsigned short sa_family; * ...