计算机二级《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和运算符来提高运行速度。