深拷贝与浅拷贝

深浅拷贝是面试经典问题,也是常见的一个坑
浅拷贝:简单的赋值拷贝操作
深拷贝:在堆区重新申请空间,进行拷贝操作
示例:

  1. class Person {
  2. public:
  3. //无参(默认)构造函数
  4. Person() {
  5. cout << "无参构造函数!" << endl;
  6. }
  7. //有参构造函数
  8. Person(int age ,int height) {
  9. cout << "有参构造函数!" << endl;
  10. m_age = age;
  11. m_height = new int(height);
  12. }
  13. //拷贝构造函数
  14. Person(const Person& p) {
  15. cout << "拷贝构造函数!" << endl;
  16. //如果不利用深拷贝在堆区创建新内存,会导致浅拷贝带来的重复释放堆区问题
  17. m_age = p.m_age;
  18. m_height = new int(*p.m_height);
  19. }
  20. //析构函数
  21. ~Person() {
  22. cout << "析构函数!" << endl;
  23. if (m_height != NULL)
  24. {
  25. delete m_height;
  26. }
  27. }
  28. public:
  29. int m_age;
  30. int* m_height;
  31. };
  32. void test01()
  33. {
  34. Person p1(18, 180);
  35. Person p2(p1);
  36. cout << "p1的年龄: " << p1.m_age << " 身高: " << *p1.m_height << endl;
  37. cout << "p2的年龄: " << p2.m_age << " 身高: " << *p2.m_height << endl;
  38. }
  39. int main() {
  40. test01();
  41. system("pause");
  42. return 0;
  43. }

总结:如果属性有在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题

  1. //This is an error program
  2. #include <iostream>
  3. using namespace std;
  4. class Person {
  5. public:
  6. Person() {
  7. m_age = 0;
  8. m_ph = NULL;
  9. cout << "Default Construct function" << endl;
  10. }
  11. Person(int age,int h) {
  12. cout << "Person's Parametric Constructed function" << endl;
  13. m_age = age;
  14. m_ph = new int(h);
  15. }
  16. ~Person() {
  17. //堆区开辟的数据释放,在析构函数中释放
  18. if (m_ph != NULL) {
  19. delete m_ph;
  20. m_ph = NULL;
  21. }
  22. cout << "Person's Destruct function" << endl;
  23. }
  24. int m_age;
  25. int* m_ph;
  26. };
  27. void exam() {
  28. Person p1(18,160);
  29. cout << "Age of p1 is " << p1.m_age << endl;
  30. cout << "height of p1 is " << *p1.m_ph << endl;
  31. Person p2(p1);
  32. cout << "Age of p2 is " << p2.m_age << endl;
  33. cout << "height of p2 is " << *p2.m_ph << endl;
  34. }
  35. int main() {
  36. exam();
  37. }
  1. #include <iostream>
  2. using namespace std;
  3. class Person {
  4. public:
  5. Person() {
  6. m_age = 0;
  7. m_ph = NULL;
  8. cout << "Default Construct function" << endl;
  9. }
  10. Person(int age,int h) {
  11. cout << "Person's Parametric Constructed function" << endl;
  12. m_age = age;
  13. m_ph = new int(h);
  14. }
  15. Person(const Person& p) {
  16. cout << "Person's copy function" << endl;
  17. m_age = p.m_age;
  18. //m_ph = p.m_ph; // This is how the complier does;
  19. m_ph = new int(*p.m_ph);
  20. //Problem solved
  21. }
  22. ~Person() {
  23. //堆区开辟的数据释放,在析构函数中释放
  24. if (m_ph != NULL) {
  25. delete m_ph;
  26. m_ph = NULL;
  27. }
  28. cout << "Person's Destruct function" << endl;
  29. }
  30. int m_age;
  31. int* m_ph;
  32. };
  33. void exam() {
  34. Person p1(18,160);
  35. cout << "Age of p1 is " << p1.m_age << endl;
  36. cout << "height of p1 is " << *p1.m_ph << endl;
  37. Person p2(p1);
  38. cout << "Age of p2 is " << p2.m_age << endl;
  39. cout << "height of p2 is " << *p2.m_ph << endl;
  40. }
  41. int main() {
  42. exam();
  43. }