第19课 对象的构造(下)
Posted wanmeishenghuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第19课 对象的构造(下)相关的知识,希望对你有一定的参考价值。
特殊的构造函数:
示例如下:
1 #include <stdio.h> 2 3 class Test 4 { 5 private: 6 int i; 7 int j; 8 public: 9 int getI() 10 { 11 return i; 12 } 13 int getJ() 14 { 15 return j; 16 } 17 /*Test(const Test& t) 18 { 19 i = t.i; 20 j = t.j; 21 } 22 Test() 23 { 24 }*/ 25 }; 26 27 int main() 28 { 29 Test t1; 30 Test t2 = t1; 31 32 printf("t1.i = %d, t1.j = %d ", t1.getI(), t1.getJ()); 33 printf("t2.i = %d, t2.j = %d ", t2.getI(), t2.getJ()); 34 35 return 0; 36 }
17-24行就是编译器替我们提供的默认构造函数和拷贝构造函数。
运行结果如下:
可以看到t1和t2中i和j的值是一样的。
当我们的类中没有编写任何的构造函数时,编译器才会给我们提供默认的构造函数,拷贝构造函数是构造函数的一种。
拷贝构造函数:
兼容C语言的方式类似于 Test t1 = t2这种初始化方式,就是用一个已存在的对象t2来初始化t1,这时候就会调用拷贝构造函数。
拷贝构造函数的玄机:
对象的初始化实验:
我们可以看到t1和t2对象中的p指向同一个内存地址。
我们在构造函数中申请了内存,就应该释放,两个对象我们需要释放两次,因为两个对象的p指向同一个内存空间,释放两次就会发生错误。
因此,我们需要手工提供拷贝构造函数进行深拷贝。
如下:
1 #include <stdio.h> 2 3 class Test 4 { 5 private: 6 int i; 7 int j; 8 int* p; 9 public: 10 int getI() 11 { 12 return i; 13 } 14 int getJ() 15 { 16 return j; 17 } 18 int* getP() 19 { 20 return p; 21 } 22 Test(const Test& t) 23 { 24 i = t.i; 25 j = t.j; 26 p = new int; 27 28 *p = *t.p; 29 } 30 Test(int v) 31 { 32 i = 1; 33 j = 2; 34 p = new int; 35 36 *p = v; 37 } 38 void free() 39 { 40 delete p; 41 } 42 }; 43 44 int main() 45 { 46 Test t1(3); 47 Test t2(t1); 48 49 printf("t1.i = %d, t1.j = %d, *t1.p = %d ", t1.getI(), t1.getJ(), *t1.getP()); 50 printf("t2.i = %d, t2.j = %d, *t2.p = %d ", t2.getI(), t2.getJ(), *t2.getP()); 51 52 t1.free(); 53 t2.free(); 54 55 return 0; 56 }
22行的拷贝构造函数进行可深拷贝。第47行的初始化就会调用这个拷贝构造函数,我们也可以写成Test t2 = t1,意义是一样的,都会调用拷贝构造函数。
运行结果如下:
t1和t2中的p指向的地址不一样,这称为它们的物理状态不一样,但是p指向的内存单元中的值是一样的,这称为逻辑状态相同。
深拷贝:
问题分析:这就是上面浅拷贝时程序崩溃的原因
一般性原则:
自定义拷贝构造函数时,必然需要实现深拷贝,要不然没有必要自定义拷贝构造函数。
数组类的改进:
1 #ifndef _INTARRAY_H_ 2 #define _INTARRAY_H_ 3 4 class IntArray 5 { 6 private: 7 int m_length; 8 int* m_pointer; 9 public: 10 IntArray(int len); 11 IntArray(const IntArray& obj); 12 int length(); 13 bool get(int index, int& value); 14 bool set(int index ,int value); 15 void free(); 16 }; 17 18 #endif
1 #include "IntArray.h" 2 3 IntArray::IntArray(int len) 4 { 5 m_pointer = new int[len]; 6 7 for(int i=0; i<len; i++) 8 { 9 m_pointer[i] = 0; 10 } 11 12 m_length = len; 13 } 14 15 IntArray::IntArray(const IntArray& obj) 16 { 17 m_length = obj.m_length; 18 19 m_pointer = new int[obj.m_length]; 20 21 for(int i=0; i<obj.m_length; i++) 22 { 23 m_pointer[i] = obj.m_pointer[i]; 24 } 25 } 26 27 int IntArray::length() 28 { 29 return m_length; 30 } 31 32 bool IntArray::get(int index, int& value) 33 { 34 bool ret = (0 <= index) && (index < length()); 35 36 if( ret ) 37 { 38 value = m_pointer[index]; 39 } 40 41 return ret; 42 } 43 44 bool IntArray::set(int index, int value) 45 { 46 bool ret = (0 <= index) && (index < length()); 47 48 if( ret ) 49 { 50 m_pointer[index] = value; 51 } 52 53 return ret; 54 } 55 56 void IntArray::free() 57 { 58 delete[]m_pointer; 59 }
主程序如下:
1 #include <stdio.h> 2 #include "IntArray.h" 3 4 int main() 5 { 6 IntArray a(5); 7 8 for(int i=0; i<a.length(); i++) 9 { 10 a.set(i, i + 1); 11 } 12 13 for(int i=0; i<a.length(); i++) 14 { 15 int value = 0; 16 17 if( a.get(i, value) ) 18 { 19 printf("a[%d] = %d ", i, value); 20 } 21 } 22 23 IntArray b = a; 24 25 for(int i=0; i<b.length(); i++) 26 { 27 int value = 0; 28 29 if( b.get(i, value) ) 30 { 31 printf("b[%d] = %d ", i, value); 32 } 33 } 34 35 a.free(); 36 b.free(); 37 38 return 0; 39 }
上述程序中我们增加了拷贝构造函数,实现了深拷贝。
运行结果如下:
小结:
以上是关于第19课 对象的构造(下)的主要内容,如果未能解决你的问题,请参考以下文章