博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【C++】五、拷贝构造与赋值构造
阅读量:2380 次
发布时间:2019-05-10

本文共 2599 字,大约阅读时间需要 8 分钟。

文章目录

1.拷贝构造

1.1 为什么存在

  • 当类的数据成员中没有指针类型的变量时,直接对两个对象进行赋值没有问题。
  • 但是一旦类的数据成员含有指针变量,那么直接对这两个对象进行赋值操作之后,这两个对象的指针都将指向同一块内存。这时,一旦其中一个对象生存期结束,释放该内存,那么另一个对象的指针就变成了野指针!这对程序危害很大

1.2 定义

拷贝构造函数是一种特殊的构造函数,它在创建对象时,是使用同一类中之前创建的对象来初始化新创建的对象。拷贝构造函数通常用于:

  • 通过使用另一个同类型的对象来初始化新创建的对象。
  • 复制对象把它作为参数传递给函数。
  • 复制对象,并从函数返回这个对象。

2.赋值构造

什么时候调用拷贝构造,什么时候调用赋值构造呢??当出现下面两种情况的时候调用赋值构造

  1. 对象直接赋值给另一个对象,且接受值的对象已经初始化过
  2. 对象以值传递方式从函数返回,且接受返回值的对象已经初始化过

3.代码

赋值构造与拷贝构造原理类似,两个放在一起对比,就可以把知识闭环成体系,加深理解

#include 
using namespace std; class Line{
public: Line( ); Line( int len ); // 简单的构造函数 Line( const Line &obj); // 拷贝构造函数,会覆盖默认拷贝构造函数 Line& operator= (const Line& a); //赋值构造函数 ~Line(); // 析构函数 //注:默认的拷贝构造是位复制,即复制地址;重写后的是按值复制 // private: int *x;};Line::Line(){
cout << "调用默认构造函数" << endl; x = new int; *x = 10; printf ("stack address: %x, point: %x, value: %d\n", this, x, *x);}// 成员函数定义,包括构造函数Line::Line(int value){
cout << "调用参数构造函数" << endl; // 为指针分配内存 x = new int; *x = value; printf ("stack address: %x, point: %x, value: %d\n", this, x, *x);}Line::Line(const Line &obj){
cout << "调用拷贝构造函数并为指针 x 分配内存" << endl; x = new int; //指针 *x = *obj.x; // 拷贝值 printf ("stack1 address: %x, point: %x, value: %d\n", this, x, *x);}Line & Line::operator=(const Line &obj){
cout << "调用赋值构造函数并为指针 x 分配内存" << endl; x = new int; //指针 *x = *obj.x; // 拷贝值 printf ("stack2 address: %x, point: %x, value: %d\n", this, x, *x);}Line::~Line(void){
printf ("释放内存 address: %x, point: %x, value: %d\n", this, x, *x); delete x;}void display(Line obj){
//在这个方法里面obj是副本,所以会调用一下拷贝构造函数初始化副本 //初始化完之后,进行业务处理,用完之后就释放掉了 cout << "line 值 : " << *obj.x <
<< endl; //【注意】 !!! 下面两行不会调用拷贝构造,但是会调用赋值构造! Line line2; line2 = line1; // 1.1 调用赋值构造函数 【赋值构造情景1】 // Line line2 = line1; // 1.2 调用拷贝构造函数【普通】 printf ("global.line2 address: %x, point: %x, value: %d\n", &line2, line2.x,*line2.x); cout << "===========" << endl; Line line3(line1); //1.3 调用拷贝构造函数【普通】 printf ("global.line3 address: %x, point: %x, value: %d\n", &line3, line3.x,*line3.x); cout << "===========" << endl; display(line1); //1.4 调用拷贝构造【副本】:方法里面是个副本,因要生成副本所以肯定要拷贝构造了 printf ("global.line1 address: %x, point: %x, value: %d\n", &line1, line1.x,*line1.x); cout << "===========" << endl; line2 = newObj();//1.5 调用赋值构造函数 【赋值构造情景2】 printf ("global.line2 address: %x, point: %x, value: %d\n", &line2, line2.x,*line2.x); cout << "===========" << endl; //2 深拷贝..... return 0;}

4.参考

  • (深拷贝)

转载地址:http://hvmxb.baihongyu.com/

你可能感兴趣的文章
Linux内核中C编程生僻用法(GNU C)
查看>>
辞职后五险一金怎么处理?
查看>>
几种开源的TCP/IP协议栈对比
查看>>
C语言之断言
查看>>
程序员技术练级攻略
查看>>
#define
查看>>
C语言之if...else PK switch...case
查看>>
关于SVN方面的问题
查看>>
深入理解C语言
查看>>
编程成就:开发人员如何升级
查看>>
如何防止代码腐烂
查看>>
va_start va_end 的使用和原理
查看>>
Linux 中的零拷贝技术,第 2 部分
查看>>
零拷贝技术的研究与实现
查看>>
零拷贝与 sendfile
查看>>
directfb显示中文
查看>>
关于SIGPIPE导致的程序退出
查看>>
setsockopt()函数用法
查看>>
TCP之send函数研究
查看>>
Linux下访问内存物理地址
查看>>