C++子对象和堆对象
本文系转载,侵删,原文链接:http://www.yesky.com/368/191868_2.shtml
一、子对象
当一个类的成员是某一个类的对象时,该对象就为子对象。子对象实际就是对象成员。如:
1 class A 2 { 3 public: 4 … 5 private: 6 … 7 }; 8 class B 9 { 10 public: 11 … 12 private: 13 A a; 14 … 15 };
其中,B类中成员a就是子对象,它是A类的对象作为B类的成员。
在类中出现了子对象或称对象成员时,该类的构造函数要包含对子对象的初始化,通常采用成员初始化表的方法来初始化子对象。在成员初始化表中包含对子对象的初始化和对类中其他成员的初始化。下面举一例子说明成员初始化的构造。
1 #include 2 3 class A 4 { 5 public: 6 A(int i, int j) { A1=i; A2=j; } 7 void print() { cout< private: 8 int A1, A2; 9 }; 10 11 class B 12 { 13 public: 14 B(int i, int j, int k):a(i, j), b(k) 15 { 16 } 17 void print(); 18 private: 19 A a; file://子对象 20 int b; 21 }; 22 23 void B::print() 24 { 25 a.print(); 26 cout< } 27 28 void main() 29 { 30 B b(6, 7, 8); 31 b.print(); 32 }
该程序的输出结果为:
6,7
8
其中,a(i, j), b(k)是成员初始化表,它有二项,前一项是给子对象a初始化,其格式如下:
<子对象名> (<参数表>)
后一项是给类B的数据成员b初始化。这一项也可以写在构造函数的函数体内,使用赋值表达式语句
b = k;
给类B的数据成员初始化。
二、堆对象
所谓堆对象是指在程序运行过程中根据需要随时可以建立或删除的对象。这种堆对象被创建在内存一些空闲的存储单元中,这些存储单元被称为堆。它们可以被创建的堆对象占有,也可以通过删除堆对象而获得释放。
创建或删除堆对象时,需要如下两个运算符:
new
delete
这两个运算符又称为动态分配内存空间运算符。new相当于C语言中malloc()函数,而delete相当于C语言中free()函数。
1. 运算符new的用法
该运算符的功能是用来创建堆对象,或者说,它是用来动态地创建对象。
new运算符使用格式如下:
new <类型说明符> (<初始值列表>)
它表明在堆中建立一个由<类型说明符>给定的类型的对象,并且由括号中的<初始值列表>给出被创建对象的初始值。如果省去括号和括号中的初始值,则被创建的对象选用缺省值。
使用new运算符创建对象时,它可以根据其参数来选择适当的构造函数,它不用sizeof来计算对象所占的字节数,而可以计算其大小。
new运算符返回一个指针,指针类型将与new所分配对象相匹配,如果不匹配可以通过强制类型的方法,否则将出现编译错。
如果new运算符不能分配到所需要的内存,它将返回0,这时的指针为空指针。
运算符new也可以用来创建数组类型的对象,即对象数组。其格式如下:
new <类名> [<算术表达式>]
其中,<算术表达式>的值为所创建的对象数组的大小。如:
A *ptr;
ptr = new A[5];
new还可用来创建一般类型的数组。如:
int *p;
p = new int[10];
使用new[]创建的对象数组或一般数组时,不能为该数组指定初始值,其初始值为缺省值。
2. 运算符delete的用法
该运算符的功能是用来删除使用new创建的对象或一般类型的指针。其格式如下:
delete <指针名>
例如:
A *ptr;
ptr = new A(5, 6);
delete ptr;
运算符delete也可用来删除使用new创建对象数组,其使用格式如下:
delete[] <指针名>
同样,delete也可以删除由new创建的一般类型的数组。如:
int *p;
p = new int[10];
delete[] p;
使用运算符delete时,应注意如下几点:
(1) 它必须使用于由运算符new返回的指针;
(2) 该运算符也适用于空指针(即其值为0的指针);
(3) 指针名前只用一对方括号符,并且不管所删除数组的维数,忽略方括号内的任何数字。
下面举一例子说明new运算符和delete运算符的使用方法。
1 #include 2 3 class AA 4 { 5 public: 6 AA(int i, int j) 7 { 8 A=i; B=j; 9 cout<<"构造函数.\n"; 10 } 11 ~AA() { cout<<"析构函数.\n"; } 12 void print(); 13 private: 14 int A, B; 15 }; 16 17 void AA::print() 18 { 19 cout< } 20 21 void main() 22 { 23 AA *a1, *a2; 24 a1 = new AA(1, 2); 25 a2 = new AA(5, 6); 26 a1->print(); 27 a2->print(); 28 delete a1; 29 delete a2; 30 }
该程序的输出结果为:
构造函数.
构造函数.
1, 2
5, 6
构造函数.
构造函数.
从程序中可以看到:用new创建对象时,要调用构造函数,用delete删除对象时,要调用析构函数。如果创建或删除的时对象数组,对象数组有多少,就调用多少次构造函数或构造函数。
在实际应用中,经常对于new运算符返回的指针进行检验,看是否分配了有效的内存空间。结合本例给出检验方法如下:
if (!a1)
{
cout<<"Heap erroe!\n";
exit(1);
}
下面再举一个使用new和delete运算符对一般指针和数组的例子。
1 #include 2 #include 3 4 void fun() 5 { 6 int *p; 7 if (p = new int) 8 { 9 *p = 5; 10 cout<<*p< delete p; 11 } 12 else 13 cout<<"Heap error!\n"; 14 } 15 16 void main() 17 { 18 fun(); 19 int *pa; 20 pa = new int[5]; 21 if (!pa) 22 { 23 cout<<"Heap error!\n"; 24 exit(1); 25 } 26 for (int i=0; i<5; i++) 27 pa[i] = i+1; 28 for (i=0; i<5; i++) 29 cout<<pa[i]<<" "; 30 cout< delete[] pa; 31 }