C++:拷贝构造函数

发布于:2024-07-06 ⋅ 阅读:(19) ⋅ 点赞:(0)

拷贝构造函数的引入

  • 用对象来初始化对象
    (1)简单变量定义时,可以直接初始化,也可以用另一个同类型变量来初始化。举例说明
    (2)用class来定义对象时,可以直接初始化,也可以用另一个对象来初始化。举例说明
  testperson xiaohong(nameq, 23, true);  //局部变量 分配在栈上
  xiaohong.printfmy();
  testperson p1(xiaohong);  //方式2:用另一个对象来初始化新定义的对象
  p1.printfmy();
  testperson p2 = p1;
  p2.printfmy();

-

  • 为什么可以
    (1)变量的直接初始化,是变量在被分配内存之后直接用初始化值去填充赋值完成初始化
    (2)变量用另一个变量来初始化,是给变量分配了内存后执行了一个内存复制操作来完成的初始化
    (3)对象的直接初始化,是对象在分配内存之后调用了相应constructor来完成的初始化
    (4)对象的用另一个对象来初始化,是对象在分配之后调用了相应的copy constructor来完成初始化

  • 拷贝构造函数
    (1)拷贝构造函数是构造函数的一种,符合构造函数的一般性规则
    (2)拷贝构造函数的引入是为了让对象在初始化时能够像简单变量一样的被直接用=来赋值
    (3)拷贝构造函数不需要重载,他的参数列表固定为const classname& xx
    (4)拷贝构造函数很合适用初始化列表来实现

//拷贝构造函数
MAN::testperson::testperson(const testperson &pn)
{
  cout << "copy constructor"  << endl;
}

//拷贝构造函数
MAN::testperson::testperson(const testperson &pn) {
  this->name = pn.name;
  this->age = pn.age;
  this->male = pn.male;

  cout << "copy constructor" << endl;
}
MAN::testperson::testperson(const testperson &pn):name(pn.name),age(pn.age),male(pn.male){
  cout << "copy constructor" << endl;
}
  string nameq = "lili";
  testperson xiaohong(nameq, 23, true);  //局部变量 分配在栈上
  xiaohong.printfmy();
  testperson p1(xiaohong);  //方式2:用另一个对象来初始化新定义的对象
  p1.printfmy();
  testperson p2 = p1;  //方式2 本质一样
  p2.printfmy();

在这里插入图片描述

浅拷贝与深拷贝

  • 浅拷贝的缺陷
    (1)上节讲的只有普通成员变量初始化的拷贝构造函数,就是浅拷贝
    (2)如果不显式提供,C++会自动提供一个全部普通成员被浅拷贝的默认copy constructor
    (3)浅拷贝在遇到有动态内存分配时就会出问题,举例演示:

  • 如何解决
    (1)不要用默认copy constructor,自己显式提供一个copy constructor,并且在其内部再次分配动态内存
    (2)这就叫深拷贝,深的意思就是不止给指针变量本身分配内存一份,也给指针指向的空间再分配内存(如果有需要还要复制内存内的值)一份
    (3)一般如果不需要深拷贝,根本就不用显式提供copy constructor,所以提供了的基本都是需要深拷贝的
    (4)拷贝构造函数不需要额外的析构函数来对应,用的还是原来的析构函数

MAN::testperson::testperson(const testperson &pn)
    : name(pn.name), age(pn.age), male(pn.male) {
  pint = new int(*pn.pint);//深拷贝
  cout << "copy constructor" << endl;
}
  string nameq = "lili";
  testperson xiaohong(nameq, 23, true);  //局部变量 分配在栈上
  testperson p1(xiaohong);  //方式2:用另一个对象来初始化新定义的对象
  *(xiaohong.pint) = 56;
  xiaohong.printfmy();

  p1.printfmy();
  testperson p2 = p1;  //方式2 本质一样
  p2.printfmy();

在这里插入图片描述

  • 如何深度理解浅拷贝和深拷贝
    (1)这个问题不是C++特有的,Java等语言也会遇到,只是语言给封起来了,而C++需要类作者自己精心处理
    (2)从编程语言学角度讲,本质上是值语义value symatics和引用语义reference symatics的差别
    (3)C学好了有linux内核阅读级别的C功底,理解这些简直太简单了

总结

理解普通变量赋值和对象赋值的区别
理解什么是浅拷贝、深拷贝,怎么实现深拷贝

学习记录,侵权联系删除。
来源:朱老师物联网大课堂


网站公告

今日签到

点亮在社区的每一天
去签到