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

来源:文书网 6.37K

为帮助同学们更好更有准备地复习计算机二级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和运算符来提高运行速度。

热门标签