1. 动态建立与释放
一般方法定义的对象是静态的,在程序运行中,对象所占用的空间不能随时释放的。C++/C语言中,可以用new运算符动态建立一个对象,用delete运算符撤销对象。
new Box;
系统开辟了一段内存空间,存放一个Box类对象,同时调用该类的构造函数,完成对象初始化。用new运算符动态分配内存后,将返回一个指向新对象的指针的值,即所分配的内存空间的起始地址。需要定义一个指向类的对象的指针存放该地址。
Box *pt; //定义一个Box类对象的指针变量pt。
pt = new Box; //在pt中存放新建对象的起始地址。
用new建立的动态对象一般是不用对象名的,而是通过指针访问,它主要用于动态的数据结构,如链表。在不需要new建立的对象的时候,可以用delete运算符予以释放。
delete pt; //释放pt指向的内存空间。
如果指针变量指向了不同的动态对象,应注意指针变量的当前指向,以免误删了对象。
在执行delete运算符时,释放了内存空间,自动调用析构函数,完成善后清理工作。
2.对象的赋值
两个同类的对象,可以相互赋值,或者可以将一个对象的值赋给另一个同类的对象。赋的值是对象中所有数据成员的值。
基本格式为:
对象1 = 对象2;
注意:对象的赋值只对其中的数据成员赋值,而不对成员函数赋值。数据成员是占存储空间的,不同对象的数据成员占有不同的存储空间,赋值过程将一个对象的数据成员复制给另一个数据成员的存储空间。但是不同的成员函数是同一个函数代码段,不能对自己赋值。
3.对象的复制
用一个已有的对象快速的复制出多个完全相同的对象。格式如下:
类名 对象2(对象1);
//或者
类名 对象1 = 对象2;
括号中的参数不是一般变量,而是对象。在建立一个新对象时调用一个特殊的构造函数---复制构造函数。形式如下:
//copy constructor definition
Box::Box(const Box &b)
{
height = b.height;
width = b.width;
length = b.length;
}
一般约定加const声明,防止使形参值不能被改变,以免调用时不慎使对象值被修改。
下面区分几个概念:
4.对象复制与对象赋值
对象的复制是建立在已经存在的对象基础之上,因此要先有对象,才能赋值。对象的赋值是从无到有的建立一个新的对象,拥有一致的结构和成员。
5.普通构造函数与复制构造函数
(1)形式上
类名(形参列表); //普通构造函数的声明,Box(int,int,int)
类名(类名 & 对象名) // 复制构造函数的声明,如Box(Box &b)
(2)普通构造函数在建立对象时被调用。复制构造函数在用已有对象复制一个新对象时被调用,
a.程序中需要新建立一个对象,并用另一个同类的对象对它初始化。
b.当函数的参数为类的对象时。在调用函数时需要将实参对象完整的传递给形参,也就是需要建立一个实参的copy,系统是通过调用复制构造函数来实现的,这样才能保证形参与实参具有完全相同的数据和结构。
void fun(Box b) //形参是类的对象
{}
int main()
{
Box box1(12,15,18);
fun(box1); //实参是类的对象,调用函数时将复制一个新的对象b
return 0;
}
c.函数返回值是类的对象。此时需要将函数中的对象复制一个临时对象并传递给函数的调用处。
Box f() //f的类型为Box类类型
{
Box box1(12,15,18);
return box1; //返回值是Box类的对象
}
int main()
{
Box box2; //定义box类的对象box2
box2 = f(); //调用f函数,并将它赋值给Box2
}
box1是在函数f中定义的,在调用f函数结束时,box1的生命周期结束。因此并不是box1带回main函数,而是函数f结束前执行return语句,调用了Box类中的复制构造函数,将box1复制给box2.
注意的是,以上都是由编译系统自动实现的,不必自己去调用。