《c++沉思录》--一个面向对象程序范例

原创 2008年09月28日 14:31:00

面向对象有三个要素:

数据抽象,继承以及动态绑定

 

问题描述:

 

1、一个表达式树包括代表常量、一元运算符、二元运算符的结点。

2、我们希望通过调用合适的函数来创建这棵树,然后打印这棵树的完整括号化形式。

 

面向对象的解决方案:

我们可以用一个联合(UNION)来容纳具体的值,用一个List来表示子结点,以包含联合(UNION)和List的类来表示结点。这些类有一个共同点:每个类都要存储一个值以及一些子结点,当然也有不少不同点,比如它们存储的值的种类,子结点的数目,继承可以捕捉这些共同点,而动态绑定帮助各个结点知道它的身份。

进一步分析,我们发现这棵树有三种结点:

1、整数表达式,无子结点

2、包含一个一元表达式,有一个子结点。

3、包含一个二元表达式,有两个子结点。

 

我们需要一个类来表示结点的"概念",但这个类并不表示具体的结点。我们将这个公共基类命名为Expr_node:

class Expr_node

{

            //友元函数,重载<<操作符用于输出

            friend ostream operator<<(ostream&, const Expr_node&)

            {

                    

            }

protected:

            virtual void print(ostream& ) const = 0;

            virtual ~Expr_node() {};

}

因为所要创建的对象都派生至Expr_node,所以提供了虚析构函数。动态绑定只用于成员函数,所以我们定义了一个虚函数print。我们希望用户使用输出操作符,而不是Print函数,那么把Print设为Protected,把operator<<设为友元。

从函数Print的声明可以看出,它是一个纯虚函数,这就使得Expr_node成为抽象基类。这就体现了我们的意图:不存在所谓的Expr_node对象。Expr_node类的存在只是为了获得公共接口。

 

输出操作符:

ostream& oprator << (ostream & o, const Expr_node e)

{

            e.print(o);

            return o;

}

 

下面定义具体的类:

1、整数,无子结点的结点类

class Int_node:public Expr_node{

            friend class Expr;

            int n;

 

            Int_node(int k) : n(k) {}

            void print(ostream & o) const { o << n; }

}

 

2、一元结点类

class Unary_node: public Expr_node{

          //friend class Expr;  

          string op;

          Expr_node * opnd;

          Unary_node(const string & a, Expr_node * b):Op(a), opnd(b) {}

          void print(ostream & o) const

          {o << "(" << op << *opnd << ")";}

}

 

 

3、二元结点类

class Binary_node: public Expr_node{

          //friend class Expr;  

          string op;

          Expr_node * left;

          Expr_node * right;

          Binary_node(const string & a, Expr_node * b,Expr_node * c):Op(a), opnd(b),opnd(c) {}

          void print(ostream & o) const

          {o << "(" << *left << op << *right << ")";}

}

 

创建一元和二元表达式的构造函数期望获得指针,于是我们可以动态分配结点:

Binary_node * t = new Binary_node("*",

                              new Unary_node("-", new Int_node(5)),

                              new Binary_node("+",new Int_node(3), new Int_node(4)));                 

 

显然这里存在一个问题,我们不再拥有内部new的对象的指针了。下一节介绍如何new 和 delete对象。

 

一个面向对象程序范例-摘自《C++沉思录》Andrew Koenig

通常认为,面向对象编程有3个要素:数据抽象、继承以及
  • locklzg
  • locklzg
  • 2014年06月10日 15:34
  • 511

《C++沉思录》-第八章- 一个面向对象程序范例

node.h #ifndef NODE_H #define NODE_H #include "expr.h" #include #include using namespace std; c...
  • shuideyidi
  • shuideyidi
  • 2013年12月10日 13:56
  • 731

C++ 沉思录》阅读笔记——类的反思

类这个概念无非是数据和方法的集合,为什么我一直困惑呢?为什么不弄清楚呢? C++中的类这个概念里有4个函数比较特殊,像我这种以前有C经验的人可能一时难以适应,它们是构造函数、析构函数、复制构造函...
  • flora_yao
  • flora_yao
  • 2015年07月02日 18:02
  • 639

C++沉思录 第八章 面向对象程序范例

c++沉思录第八章的示例程序很有意思。程序虽小,却很好地诠释了面向对象编程的思想。 正如书上说的仔细研究还是有所收获的。先上代码codeExpr_node.h#pragma once #includ...
  • maple1149
  • maple1149
  • 2015年08月05日 16:51
  • 430

[沉思录(中英双语)·典藏本].(古罗马)奥勒留.扫描版.PDF 免费下载

下载地址:[沉思录(中英双语)·典藏本].(古罗马)奥勒留.扫描版.PDF
  • jiongyi1
  • jiongyi1
  • 2017年11月13日 21:48
  • 227

《C++沉思录》读书笔记之代理类

#include #include int main() { int i; for( i=0;i
  • KangRoger
  • KangRoger
  • 2014年06月11日 21:00
  • 1139

C++沉思录读书笔记(8章)-一个面向对象程序范例1

这个例子很好的展示了面向对象编程的三个要素:数据抽象、继承和动态绑定。 问题:算术表达式的表达式树, 如(-5)*(3+4)对应的表达式树为: 我们希望通过调用合适的函数来创建这样的树...
  • yucan1001
  • yucan1001
  • 2011年11月01日 15:13
  • 884

C++沉思录读书笔记(8章)-一个面向对象程序范例2

此回是针对上回所设计方案的扩展,下面将会演示 (1)如何增加计算表达式的值的功能 (2)如何增加新的节点类型(已经有表示单个数、一元操作符、二元操作符的节点类型Int_node\Unary_nod...
  • yucan1001
  • yucan1001
  • 2011年11月01日 17:24
  • 995

读书笔记∣概率论沉思录 01

读书笔记:概率论沉思录
  • zhaozhn5
  • zhaozhn5
  • 2017年09月09日 21:09
  • 335

<<C++ 沉思录>> 中文人民邮电出版 勘误

> 中文人民邮电出版 勘误 这本中文版里面有各种坑爹的小错误. 比方说变量名的大小写, 同一个变量, 出现了大小写不一致, 等等问题都有. 然后今天感觉遇到了个语法问题. 关于继承权限的问题....
  • u011368821
  • u011368821
  • 2015年05月22日 15:33
  • 1004
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《c++沉思录》--一个面向对象程序范例
举报原因:
原因补充:

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