链表中链入对象

来源:互联网 发布:2016黑帽seo 编辑:程序博客网 时间:2024/04/29 09:58
 似乎你也注重到了,不管怎么定义,似乎一个链表中的对象都是同一类型的。而实际上,这也是必须的,否则,返回节点中的数据这样的函数的返回值的类型是什么呢?但是,人的要求是无止境的……(省略本人感慨若干百字)。
把不同的对象链在一个链表中的目的是为了方便使用,现在一定记住这个原则,后面的讨论都是基于这个原则的,否则,我们就是技术狂人了——偏偏实现一些看起来不可能的事情。

  达到这个目标的原理其实很简单,只要把不同类型的对象变成同样的类型就可以了。看下面的结构定义:
  strUCt Mobject
  {
  void *p;
  int ObjectType;
  };
  将一个对象链入链表时,将指向这个对象的指针赋给p,同时记录对象类型。当取得这个节点的时候,根据ObjectType的值来确定p指的对象类型,从而还原指针类型,也就得到了原来的对象。

  后面讲到的广义表实际上采用的就是这种方法。显而易见的,这样的Mobject支持的对象是预先确定的,你将自己维护ObjectType列表,每添加一种类型的支持,你需要在ObjectType列表中给出它的替代值,然后在相应的switch(ObjectType)给出这种类型的case语句。很烦人是吧,下面给出另一种方法,其实还是这个原理,不同的是,把这个烦人的工作交给编译器了。

  还记得前边强调的原则吗,为什么我们将不同类型的对象放在一个链表中呢?很显然,我们想达到这样的一个效果:比如说,我们在一个链表中储存了三角形,直线,圆等图形的参数,我们希望对某个节点使用Draw()方法,就重绘这个图形;使用Get()则得到这个图形的各个参数;使用Put()则修改图形的参数。可以看出,这些不同的对象实际上有同样的行为,只是实现的方法不同。
更多文章 更多内容请看C/C++技术专题  数据结构  数据结构教程专题,或   C++的多态性正好可以实现我们的构想。关于这方面,请参阅相关的C++书籍(我看的是《C++编程思想》)。请看如下的例子:

  #ifndef Shape_H
  #define Shape_H
  
  class Shape
  {
  public:
  virtual void Input() = 0;
  virtual void Print() = 0;
  Shape(){};
  virtual ~Shape(){};
  
  };
  
  #endif


  【说明】定义一个抽象基类,有两个行为,Input()为输入图形参数,Print()为打印图形参数。图省事,只是简单的说明问题而已。

  #ifndef Point_H
  #define Point_H
  
  class Point
  {
  public:
  void Put()
  {
  cout << "x坐标为:";
  cin >> x;
  cout << "y坐标为:";
  cin >> y;
  }
  
  void Get()
  {
  cout << endl << "x坐标为:" << x;
  cout << endl << "y坐标为:" << y;
  }
  
  virtual ~Point(){};
  
  private:
  int x;
  int y;
  };
  
  #endif

  【说明】点的类定义与实现。

  #ifndef Circle_H
  #define Circle_H

  
  #include "Shape.h"
  #include "Point.h"
  
更多文章 更多内容请看C/C++技术专题  数据结构  数据结构教程专题,或   class Circle : public Shape
  {
  public:
  void Input()
  {
  cout << endl << "输入圆的参数";
  cout << endl << "输入圆心点的坐标:" << endl;
  center.Put();
  cout << endl << "输入半径:";
  cin >> radius;
  }
  
  void Print()
  {
  cout << endl << "圆的参数为";
  cout << endl << "圆心点的坐标:" << endl;
  center.Get();
  cout << endl << "半径:" << radius;
  }
  virtual ~Circle(){};
  
  private:
  int radius;
  Point center;
  };
  
  #endif

  【说明】圆的类定义与实现。继续Shape类的行为。

  #ifndef Line_H
  #define Line_H
  
  #include "Shape.h"
  #include "Point.h"
  
  class Line : public Shape
  {
  public:
  void Input()
  {
  cout << endl << "输入直线的参数";
  cout << endl << "输入端点1的坐标:" << endl;
  point1.Put();
  cout << endl << "输入端点2的坐标:" << endl;
  point2.Put();
  }
  
  void Print()
  {
  cout << endl << "直线的参数为";
  cout << endl << "端点1的坐标:";
  point1.Get();
  cout << endl << "端点2的坐标:";
  point2.Get();
  }
  
  virtual ~Line(){};
  
  private:
  Point point1;
  Point point2;
  };
  
  #endif

  【说明】直线类的定义与实现。继续Shape的行为。

  #ifndef ListTest_H
  #define ListTest_H
  
  #include
  #include "List.h"
  #include "Circle.h"
  #include "Line.h"
  void ListTest_MObject()
  {
  List a;
  Shape *p1 = new Circle;
  Shape *p2 = new Line;
  p1->Input();
  p2->Input();
  a.Insert(p1);
  a.Insert(p2);
  Shape *p = *a.Next();
  p->Print();
  delete p;
  a.Put(NULL);
  p = *a.Next();
  p->Print();
  delete p;
  a.Put(NULL);
  }
  #endif
更多文章 更多内容请看C/C++技术专题  数据结构  数据结构教程专题,或   【说明】这是测试函数,使用方法是在含有main()的cpp文件头部加入#include “ListTest.h”,然后调用ListTest_Mobject()。这是一个简单的例子,可以看出,删除这样的链表节点需要两个步骤,先delete链表节点data域里指针所指的对象,然后才能删除链表节点。
同样,析构这样链表的时候,也需要注重这个问题。不然的话,你的程序运行一次内存就少一点(可能不是这样,据说操作系统在程序中止时可以回收动态内存,但后面的结论是对的),假如是个频繁调用的函数,当运行一段时间后,你的系统就瘫痪了。所以,使用这样的链表最好是派生一个新的链表类,实现相应的操作。例如这样:


  class ShapeList : public List
  {
  public:
  BOOL SL_Remove()
    {
  Shape *p = *Get();
  delete p;
  return Remove();
  }
  };
  【闲话】不知你是不是对这样的语句Shape *p = *a.Next();p->Print();不甚理解,还觉得有点罗嗦。那你试试这样的语句*a.Next()->Print();能不能编译通过
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 生完二胎脑子不好使怎么办 羽毛球鞋买小了怎么办 羽毛球鞋买大了怎么办 感觉自己脑子越来越笨了怎么办? 生完孩子后身体素质差怎么办 胃口太好越来越胖怎么办 心情一紧张心跳手抖怎么办 消防兵新兵连俯卧撑不够怎么办 cf枪王永久禁赛怎么办 换了手机号花呗怎么办 xp系统无限重启怎么办 魔域配置资源读取错误怎么办 魔域异地交易了怎么办 魔域手游宝宝亲密度不够怎么办 魔域手游怎么改密码忘了怎么办 魔域装备注灵怎么办 lol外服账号忘记了怎么办 美服lol下载慢怎么办 台服天堂2延迟怎么办 梦幻专用瑞兽没有泰山怎么办 冲错了游戏点券怎么办 新手玩联盟很菜怎么办 cf玩一会儿卡退怎么办 魔域先锋区封号了怎么办 吃了减肥药头疼怎么办 冬天没用完的霜怎么办 手表带起来大了怎么办 碰到舞警打人该怎么办 合租者偷了东西却没有证据怎么办 钥匙锁在房间了怎么办 家里门钥匙丢了怎么办 合租朝北晒衣服怎么办 卧室门钥匙丢了怎么办 邻居在我家防盗窗上凉被子怎么办 有钥匙打不开门怎么办 白色腈纶衣服洗完发黄怎么办 在部队有人整你怎么办 老公掉粪坑了你怎么办图片 好久没跑步腿疼怎么办 跑1000米要5分钟怎么办 孩子眼睛近视加散光怎么办