【C++学习】多态——解析树实例分析
2012-12-10 20:59
405 查看
作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/
场景:
![](http://images.cnblogs.com/cnblogs_com/gnuhpc/201212/201212102058421715.jpg)
分析: 每个类的节点都必须提供它自己的Calc方法,所以采用多态进行操作。我们将Node节点和BinNode节点设计为抽象类,抽象类是不能实例化的类,它们只能作为其他类的父类。一个包含一个或多个纯虚函数的类称为抽象类,一个没有具体实现的函数称为纯虚函数,只有从一个抽象类派生的类以及为所有纯虚函数提供了实现代码的类才能被实例化。一般来说,若一个类有一个纯虚函数,它可能同时需要一个虚析构函数。所以类设计层次如下:
![](http://images.cnblogs.com/cnblogs_com/gnuhpc/201212/201212102058438269.jpg)
代码:
Tree.h
#if !defined (TREE_H)
#define TREE_H
// (c) Bartosz Milewski 2000
class Node
{
public:
virtual ~Node () {}//设置一个虚析构函数
virtual double Calc () const = 0;//设置一个纯虚函数,也就是=0的意义所在。
};
class NumNode: public Node//继承了Node
{
public:
NumNode (double num) : _num (num ) {}
double Calc () const;
private:
const double _num;
};
class BinNode: public Node
{
public:
BinNode (Node * pLeft, Node * pRight)
: _pLeft (pLeft), _pRight (pRight) {}
~BinNode ();
protected: //使用protected的原因是它可以被派生类直接使用,这样我们不用提供setter和getter来进行访问了。
Node * const _pLeft;
Node * const _pRight;
};
class AddNode: public BinNode
{
public:
AddNode (Node * pLeft, Node * pRight)
: BinNode (pLeft, pRight) {}
double Calc () const;
};
class MultNode: public BinNode
{
public:
MultNode (Node * pLeft, Node * pRight)
: BinNode (pLeft, pRight) {}
double Calc () const;
};
#endif
Tree.cpp
// (c) Bartosz Milewski 2000
#include "Tree.h"
#include <iostream>
double NumNode::Calc () const
{
std::cout << "Numeric node " << _num << std::endl;
return _num;
}
BinNode::~BinNode ()
{
delete _pLeft;
delete _pRight;
}
double AddNode::Calc () const
{
std::cout << "Adding/n";
return _pLeft->Calc () + _pRight->Calc (); //直接访问父类protected成员
}
double MultNode::Calc () const
{
std::cout << "Multiplying/n";
return _pLeft->Calc () * _pRight->Calc () ;//直接访问父类protected成员
}
int main ()
{
// ( 20.0 + (-10.0) ) * 0.1
Node * pNode1 = new NumNode (20.0);
Node * pNode2 = new NumNode (-10.0);
Node * pNode3 = new AddNode (pNode1, pNode2);
Node * pNode4 = new NumNode (0.1);
Node * pNode5 = new MultNode (pNode3, pNode4);
std::cout << "Calculating the tree/n";
// tell the root to calculate itself ,从根开始计算
double x = pNode5->Calc ();
std::cout << "Result: " << x << std::endl;
delete pNode5; // and all children
}
注:要是用C语言进行实现的时候我们不可以避免使用Switch语句,这个例子也说明在C++中仅在不能使用多态的时候使用Switch语句。
参考文献:http://www.informit.com/articles/article.aspx?p=21484
作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/
出处:http://www.cnblogs.com/gnuhpc/
场景:
![](http://images.cnblogs.com/cnblogs_com/gnuhpc/201212/201212102058421715.jpg)
分析: 每个类的节点都必须提供它自己的Calc方法,所以采用多态进行操作。我们将Node节点和BinNode节点设计为抽象类,抽象类是不能实例化的类,它们只能作为其他类的父类。一个包含一个或多个纯虚函数的类称为抽象类,一个没有具体实现的函数称为纯虚函数,只有从一个抽象类派生的类以及为所有纯虚函数提供了实现代码的类才能被实例化。一般来说,若一个类有一个纯虚函数,它可能同时需要一个虚析构函数。所以类设计层次如下:
![](http://images.cnblogs.com/cnblogs_com/gnuhpc/201212/201212102058438269.jpg)
代码:
Tree.h
#if !defined (TREE_H)
#define TREE_H
// (c) Bartosz Milewski 2000
class Node
{
public:
virtual ~Node () {}//设置一个虚析构函数
virtual double Calc () const = 0;//设置一个纯虚函数,也就是=0的意义所在。
};
class NumNode: public Node//继承了Node
{
public:
NumNode (double num) : _num (num ) {}
double Calc () const;
private:
const double _num;
};
class BinNode: public Node
{
public:
BinNode (Node * pLeft, Node * pRight)
: _pLeft (pLeft), _pRight (pRight) {}
~BinNode ();
protected: //使用protected的原因是它可以被派生类直接使用,这样我们不用提供setter和getter来进行访问了。
Node * const _pLeft;
Node * const _pRight;
};
class AddNode: public BinNode
{
public:
AddNode (Node * pLeft, Node * pRight)
: BinNode (pLeft, pRight) {}
double Calc () const;
};
class MultNode: public BinNode
{
public:
MultNode (Node * pLeft, Node * pRight)
: BinNode (pLeft, pRight) {}
double Calc () const;
};
#endif
Tree.cpp
// (c) Bartosz Milewski 2000
#include "Tree.h"
#include <iostream>
double NumNode::Calc () const
{
std::cout << "Numeric node " << _num << std::endl;
return _num;
}
BinNode::~BinNode ()
{
delete _pLeft;
delete _pRight;
}
double AddNode::Calc () const
{
std::cout << "Adding/n";
return _pLeft->Calc () + _pRight->Calc (); //直接访问父类protected成员
}
double MultNode::Calc () const
{
std::cout << "Multiplying/n";
return _pLeft->Calc () * _pRight->Calc () ;//直接访问父类protected成员
}
int main ()
{
// ( 20.0 + (-10.0) ) * 0.1
Node * pNode1 = new NumNode (20.0);
Node * pNode2 = new NumNode (-10.0);
Node * pNode3 = new AddNode (pNode1, pNode2);
Node * pNode4 = new NumNode (0.1);
Node * pNode5 = new MultNode (pNode3, pNode4);
std::cout << "Calculating the tree/n";
// tell the root to calculate itself ,从根开始计算
double x = pNode5->Calc ();
std::cout << "Result: " << x << std::endl;
delete pNode5; // and all children
}
注:要是用C语言进行实现的时候我们不可以避免使用Switch语句,这个例子也说明在C++中仅在不能使用多态的时候使用Switch语句。
参考文献:http://www.informit.com/articles/article.aspx?p=21484
作者:gnuhpc
出处:http://www.cnblogs.com/gnuhpc/
相关文章推荐
- C++学习 C++函数模板与类模板实例解析
- 【Java学习笔记之二十二】解析接口在Java继承中的用法及实例分析
- C++解析JSON进行网络传输--jsoncpp的学习分析
- 【Java学习笔记之二十二】解析接口在Java继承中的用法及实例分析
- 2009-2010网络最热的 嵌入式学习|ARM|Linux|wince|ucos|经典资料与实例分析 完整版
- C++学习总结(十四)——类的运算符的重载原理,以及重载的实例
- python解析xml文件实例分析
- C/C++学习笔记2 - cin深入分析(上) - cin输入操作处理(原创)
- Intel平台下linux中ELF文件动态链接的加载、解析及实例分析(二): 函数解析与卸载
- Python多重继承的方法解析执行顺序实例分析
- 时序图学习7_实例分析
- UML需求分析步骤实例解析
- POCO C++库学习和分析 -- 序
- 利用a标签自动解析URL分析网址实例
- C++实现图的邻接矩阵存储和广度、深度优先遍历实例分析
- [Python][Scikit-learn][学习笔记01]线性回归之波士顿房价实例分析
- 转:C++学习重点分析
- input子系统学习笔记六 按键驱动实例分析下
- 深度学习利器:分布式TensorFlow及实例分析
- POCO C++库学习和分析——任务