试题 百分网手机站

计算机二级《C++》考点解析:堆和类数组

时间:2020-08-24 15:03:35 试题 我要投稿

计算机二级《C++》考点解析:堆和类数组

  为帮助同学们更好更有准备地复习计算机二级C++,以下是百分网小编搜索整理的计算机二级《C++》考点解析:堆和类数组,供参考复习,希望对大家有所帮助!想了解更多相关信息请持续关注我们应届毕业生考试网!

  一、构造函数和析构函数

  前面的例子已经运用了new和来为类对象分配和释放内存。当使用new为类对象分配内存时,编译器首先用new运算符分配内存,然后调用类的构造函数;类似的,当使用来释放内存时,编译器会首先调用泪的析构函数,然后再调用运算符。

  #include iostream.h

  class Date

  {

  int mo,da,yr;

  public:

  Date() { cout < ~Date() { cout< }

  int main()

  {

  Date* dt = new Date;

  cout < dt;

  return 0;

  }

  程序定义了一个有构造函数和析构函数的Date类,这两个函数在执行时会显示一条信息。当new运算符初始化指针dt时,执行了构造函数,当运算符释放内存时,又执行了析构函数。

  程序输出如下:

  Date constructor

  Process the date

  Date destructor

  二、堆和类数组

  前面提到,类对象数组的每个元素都要调用构造函数和析构函数。下面的例子给出了一个错误的释放类数组所占用的内存的例子。

  #include iostream.h

  class Date

  {

  int mo, da, yr;

  public:

  Date() { cout < ~Date() { cout< }

  int main()

  {

  Date* dt = new Date[5];

  cout < dt; //这儿

  return 0;

  }

  指针dt指向一个有五个元素的数组。按照数组的定义,编译器会让new运算符调用Date类的构造函数五次。但是被调用时,并没有明确告诉编译器指针指向的Date对象有几个,所以编译时,只会调用析构函数一次。下面是程序输出;

  Date constructor

  Date constructor

  Date constructor

  Date constructor

  Date constructor

  Process the date

  Date destructor

  为了解决这个问题,C++允许告诉运算符,正在删除的那个指针时指向数组的,程序修改如下:

  #include iostream.h

  class Date

  {

  int mo, da, yr;

  public:

  Date() { cout < ~Date() { cout< }

  int main()

  {

  Date* dt = new Date[5];

  cout < [] dt; //这儿

  return 0;

  }

  最终输出为:

  Date constructor

  Date constructor

  Date constructor

  Date constructor

  Date constructor

  Process the date

  Date destructor

  Date destructor

  Date destructor

  Date destructor

  Date destructor

  三、重载new和运算符

  前面已经介绍了如何用new和运算符函数来动态第管理内存,在那些例子中使用的都是全局的new和运算符。我们可以重载全局的new和运算符,但这不是好的想法,除非在进行低级的系统上或者嵌入式的编程。

  但是,在某个类的内部重载new和运算符时可以的。这允许一个类有它自己的new和运算符。当一个类需要和内存打交道时,采用这种方法来处理其中的细节,可以获得很搞的效率,同时避免了使用全局new和运算符带来的额外开销。因为全局堆操作时调用操作系统函数来分配和释放内存,这样效率很低。

  如果确定某个类在任何时候,其实例都不会超过一个确定的值,那么就可以一次性为类的所有实例分配足够的内存,然后用该类的new和运算符来管理这些内存。下面的程序说明了如何对new和进行重载。

  #include iostream.h

  #include string.h

  #include stddef.h

  #include new.h

  const int maxnames = 5;

  class Names

  {

  char name[25];

  static char Names::pool[];

  static bool Names::inuse[maxnames];

  public:

  Names(char* s) { strncpy(name,s,sizeof(name)); }

  void* operator new(size_t) throw(bad_alloc);

  void operator (void*) throw();

  void display() const { cout < };

  char Names::pool[maxnames * sizeof(Names)];

  bool Names::inuse[maxnames];

  void* Names::operator new(size_t) throw(bad_alloc)

  {

  for(int p=0; p {

  if(!inuse[p])

  {

  inuse[p] = true;

  return pool+p*sizeof(Names);

  }

  }

  throw bad_alloc();

  }

  void Names::operator (void* p) throw()

  {

  if(p!=0)

  inuse[((char*)p - pool)/sizeof(Names)] = false;

  }

  int main()

  {

  Names* nm[maxnames];

  int i;

  for(i=0; i {

  cout < char name[25];

  cin >> name;

  nm[i] = new Names(name);

  }

  for(i=0; i {

  nm[i]- >display();

   nm[i];

  }

  return 0;

  }

  上面的程序提示输入5个姓名,然后显示它们。程序中定义了名为Names的类,它的构造函数初始化对象的name值。这个类定义了自己的new和运算符。这是因为程序能保证不会一次使用超过maxnames个姓名,所以可以通过重载默认的new和运算符来提高运行速度。