non-virtual interface(NVI)手法:令用户通过public non-virtual成员函数间接调用private virtual函数,将这个non-virtual函数称为virtual函数的wrapper.wrapper确保得以在一个virtual函数被调用之前设定好适当场景,并在调用结束之后清理场景.注意此时用指针或引用调用该non-virtual成员函数时,该non-virtual成员函数调用的virtual函数取决于指针或引用的动态类型,即存在多态

enum ShapeColor { Red, Green, Blue };
class Shape
{
public:
void draw(ShapeColor color = Red) const
{
doDraw(color);
}
private:
virtual void doDraw(ShapeColor color) const = ;
}; class Rectangle :public Shape
{
public: private:
virtual void doDraw(ShapeColor color) const;
}; void Rectangle::doDraw(ShapeColor color) const
{
cout << "Rectangle's doDraw" << "color= " << color << endl;
} void main()
{
Shape*p = new Rectangle;
////输出:Rectangle's doDrawcolor= 0
p->draw();
system("pause");
}

enum ShapeColor { Red, Green, Blue };
class Shape
{
public:
void draw(ShapeColor color = Red)const
{
doDraw(color);
}
private:
virtual void doDraw(ShapeColor color) const
{
cout << "Shape's doDraw" << "color= " << color << endl;
}
}; class Rectangle :public Shape
{
public: private:
virtual void doDraw(ShapeColor color) const;
}; void Rectangle::doDraw(ShapeColor color) const
{
cout << "Rectangle's doDraw" << "color= " << color << endl;
} /*
输出:
Shape's doDrawcolor= 0
Rectangle's doDrawcolor= 0
*/
void main()
{
Shape*p = new Shape;
p->draw();
delete p;
p = NULL;
Shape*q = new Rectangle;
q->draw();
delete q;
q = NULL; system("pause");
}

enum ShapeColor { Red, Green, Blue };
class Shape
{
public: void draw(ShapeColor color = Red)const
{
doDraw(color);
}
private:
void doDraw(ShapeColor color) const
{
cout << "Shape's doDraw" << "color= " << color << endl;
}
}; class Rectangle :public Shape
{
public: private:
void doDraw(ShapeColor color) const;
}; void Rectangle::doDraw(ShapeColor color) const
{
cout << "Rectangle's doDraw" << "color= " << color << endl;
}
/*
输出:
Shape's doDrawcolor= 0
Shape's doDrawcolor= 0
*/
int main()
{
Shape*p = new Shape;
p->draw();
delete p;
p = NULL;
Shape*q = new Rectangle;
q->draw();
delete q;
q = NULL; system("pause");
return ;
}

c++之NVI手法的更多相关文章

  1. Effective C++ -----条款35:考虑virtual函数以外的其他选择

    virtual函数的替代方案包括NVI手法及Strategy设计模式的多种手法.NVI手法自身是一个特殊形式的Template Method设计模式. 将机能从成员函数移到class外部函数,带来的一 ...

  2. Effective C++ 的55个条款

    看完Effective C++才觉得平时程序设计时需要注意的一些问题,有一定的收获,不过因为没什么项目实践, 并未很深入了解具体情况如何,还需后继实践~ 列举一下55个条款: 1. 视C++为一个语言 ...

  3. 考虑virtual函数以外的其它选择

    详情见<Effective C++>item35 1.使用non-virtual interface(NVI)手法,这是Template Method设计模式的一种特殊形式. 它以publ ...

  4. Effective C++ 总结(三)

    五.实现  条款26:尽可能延后变量定义式的出现时间 如果你定义了一个变量且该类型带一个构造函数或析构函数,当程序到达该变量时,你要承受构造成本,而离开作用域时,你要承受析构成本.为了减少这个成本,最 ...

  5. Effective C++:条款35:考虑virtual函数以外的其它选择

    游戏中的人物伤害值计算问题. (一)方法(1):一般来讲能够使用虚函数的方法: class GameCharacter { public: virtual int healthValue() cons ...

  6. Effective C++笔记 55条编程法则

    1.  视C++为一个语言联邦 C++高效编程守则视状况而变化,取决于你使用C++的哪一部分. 2.  尽量以const,enum.inline替代#define 1) 对于单纯常量,最好以const ...

  7. EC读书笔记系列之16:条款35、36、37、38、39、40

    条款35 考虑virtual函数以外的其他选择 记住: ★virtual函数的替代方案包括NVI手法及Strategy模式的多种形式.NVI手法自身是一个特殊形式的Template Method模式 ...

  8. Effective C++:条款37:绝不又一次定义继承而来的缺省參数值

    因为又一次定义继承而来的non-virtual函数是不对的(见上一个条款),所以这个条款就将问题局限于:绝不又一次定义继承一个带有缺省參数值的virtual函数. (一) virtual函数是动态绑定 ...

  9. EffectiveC++ 第6章 继承与面向对象设计

    我根据自己的理解,对原文的精华部分进行了提炼,并在一些难以理解的地方加上了自己的"可能比较准确"的「翻译」. Chapter 6 继承与面向对象设计 Inheritance and ...

随机推荐

  1. vscode vue template 下 style 的样式自动提示 #bug 这个搞完vue语法esLint就又不好使了,ERR

    网上都是 "*.vue": "vue",改成"*.vue": "html" 就ok了   "files.ass ...

  2. 如何在一次请求中通过JS中获取Url中的参数

    从A跳转到B,携带参数 例如: /pc/B.jsp?item=123456 B页面在js可以直接用 var item='${param.item}'; 这样就拿到啦 还有一种方法 定义一个函数   f ...

  3. 加快create-react-app的方法

    npm config get registry 查看npm源,默认源是 https://registry.npmjs.org/ npm config set registry https://regi ...

  4. element-ui date-picker 设置结束时间大于等于开始时间且开始时间小于等于结束时间

    Part.1  问题 date-picker 组件在使用时,默认对时间是没有限制的,可以随便选择区间,官方文档添加了快捷选项,如:一周丶一月... 但是从用户体验方面出发,我们还是希望对时间进行有利的 ...

  5. select onchange事件的使用

    <select name="expireDay" id="expireDay" class="form-control" onchan ...

  6. vue 点击按钮弹窗,点击关闭按钮关闭弹窗。

    <div @click="btnfc()">点击弹窗按钮</div> <div v-show="show"> <div ...

  7. canvas之刮刮乐

    效果图: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  8. POJ-1011(sticks,深搜)

    Description George took sticks of the same length and cut them randomly until all parts became at mo ...

  9. MySQL本地登录及数据库导入导出

    注意:本地MySQL服务要开启 更新整个数据库 1.将正式服务器上的数据库做备份 登录到正式服务器,执行如下命令:(注意空格) mysqldump -uroot –p密码 数据库名 -P 接口 --d ...

  10. CentOS6.8下安装Docker

    原文章链接https://www.cnblogs.com/baolong/p/5743420.html. 由于在自己安装的虚拟机上打开linux终端命令行输入uname -a 以及cat /etc/r ...