C++第36课--经典问题解析(三) 赋值操作符重载与拷贝构造函数,字符串string类...

本文学习自 狄泰软件学院 唐佐林老师的 C++课程


在这里插入图片描述

在这里插入图片描述

实验1:默认的赋值操作符重载

#include <iostream>
#include <string>

using namespace std;

class Test
{
    int* m_pointer;
public:
    Test()
    {
        m_pointer = NULL;
    }
    Test(int i)
    {
        m_pointer = new int(i);
    }

    void print()
    {
        cout << "m_pointer = " << hex << m_pointer << endl;
    }
    ~Test()
    {
        delete m_pointer;
    }
};

int main()
{
    Test t1 = 1;
    Test t2;
    
    t2 = t1;
    
    t1.print();
    t2.print();
    
    return 0;
}


mhr@ubuntu:~/work/c++$ 
mhr@ubuntu:~/work/c++$ g++ 36-1.cpp 
mhr@ubuntu:~/work/c++$ ./a.out 
m_pointer = 0x1f6ac20
m_pointer = 0x1f6ac20
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000001f6ac20 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x77725)[0x7faae22a4725]
/lib/x86_64-linux-gnu/libc.so.6(+0x7ff4a)[0x7faae22acf4a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7faae22b0abc]
./a.out[0x400dc3]
./a.out[0x400b68]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7faae224d830]
./a.out[0x400a29]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:01 12848358                           /home/mhr/work/c++/a.out
00601000-00602000 r--p 00001000 08:01 12848358                           /home/mhr/work/c++/a.out
00602000-00603000 rw-p 00002000 08:01 12848358                           /home/mhr/work/c++/a.out
01f59000-01f8b000 rw-p 00000000 00:00 0                                  [heap]
7faadc000000-7faadc021000 rw-p 00000000 00:00 0 
7faadc021000-7faae0000000 ---p 00000000 00:00 0 
7faae1f24000-7faae202c000 r-xp 00000000 08:01 266752                     /lib/x86_64-linux-gnu/libm-2.23.so
7faae202c000-7faae222b000 ---p 00108000 08:01 266752                     /lib/x86_64-linux-gnu/libm-2.23.so
7faae222b000-7faae222c000 r--p 00107000 08:01 266752                     /lib/x86_64-linux-gnu/libm-2.23.so
7faae222c000-7faae222d000 rw-p 00108000 08:01 266752                     /lib/x86_64-linux-gnu/libm-2.23.so
7faae222d000-7faae23ed000 r-xp 00000000 08:01 266682                     /lib/x86_64-linux-gnu/libc-2.23.so
7faae23ed000-7faae25ec000 ---p 001c0000 08:01 266682                     /lib/x86_64-linux-gnu/libc-2.23.so
7faae25ec000-7faae25f0000 r--p 001bf000 08:01 266682                     /lib/x86_64-linux-gnu/libc-2.23.so
7faae25f0000-7faae25f2000 rw-p 001c3000 08:01 266682                     /lib/x86_64-linux-gnu/libc-2.23.so
7faae25f2000-7faae25f6000 rw-p 00000000 00:00 0 
7faae25f6000-7faae260c000 r-xp 00000000 08:01 266720                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7faae260c000-7faae280b000 ---p 00016000 08:01 266720                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7faae280b000-7faae280c000 rw-p 00015000 08:01 266720                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7faae280c000-7faae297e000 r-xp 00000000 08:01 4465698                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7faae297e000-7faae2b7e000 ---p 00172000 08:01 4465698                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7faae2b7e000-7faae2b88000 r--p 00172000 08:01 4465698                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7faae2b88000-7faae2b8a000 rw-p 0017c000 08:01 4465698                    /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21
7faae2b8a000-7faae2b8e000 rw-p 00000000 00:00 0 
7faae2b8e000-7faae2bb4000 r-xp 00000000 08:01 266654                     /lib/x86_64-linux-gnu/ld-2.23.so
7faae2d96000-7faae2d9b000 rw-p 00000000 00:00 0 
7faae2db0000-7faae2db3000 rw-p 00000000 00:00 0 
7faae2db3000-7faae2db4000 r--p 00025000 08:01 266654                     /lib/x86_64-linux-gnu/ld-2.23.so
7faae2db4000-7faae2db5000 rw-p 00026000 08:01 266654                     /lib/x86_64-linux-gnu/ld-2.23.so
7faae2db5000-7faae2db6000 rw-p 00000000 00:00 0 
7ffcb98e8000-7ffcb9909000 rw-p 00000000 00:00 0                          [stack]
7ffcb9970000-7ffcb9972000 r--p 00000000 00:00 0                          [vvar]
7ffcb9972000-7ffcb9974000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted (core dumped)
mhr@ubuntu:~/work/c++$ 

报错,默认的赋值操作符重载与默认的拷贝构造函数有相同的存在意义。当涉及到对空间的申请是,调用默认的赋值操作符重载活默认的拷贝构造函数,都是使得两个指针指向同一个内存空间,程序结束时候,发生重读释放同一块内存空间的错误。

实验2:赋值操作符重载

#include <iostream>
#include <string>

using namespace std;

class Test
{
    int* m_pointer;
public:
    Test()
    {
        m_pointer = NULL;
    }
    Test(int i)
    {
        m_pointer = new int(i);
    }

	//拷贝构造函数
    Test(const Test& obj)
    {
        m_pointer = new int(*obj.m_pointer);
    }

	/*
	赋值操作符重载函数
	函数返回值 必须是 Test&,返回对象本身,这样是为了可以连续赋值。
	函数的参数必须是 const Test&
	*/
    Test& operator = (const Test& obj)
    {
    	//防止自赋值
        if( this != &obj )
        {
            delete m_pointer;
            m_pointer = new int(*obj.m_pointer);
        }
        
        //返回当前对象
        return *this;
    }
    void print()
    {
        cout << "m_pointer = " << hex << m_pointer << endl;
    }
    ~Test()
    {
        delete m_pointer;
    }
};

int main()
{
    Test t1 = 1;
    Test t2;
    
    t2 = t1;
    
    t1.print();
    t2.print();
    
    return 0;
}


mhr@ubuntu:~/work/c++$ g++ 36-1.cpp 
mhr@ubuntu:~/work/c++$ ./a.out 
m_pointer = 0x2050c20
m_pointer = 0x2050c40
mhr@ubuntu:~/work/c++$ 

拷贝构造函数 VS 赋值操作符重载

拷贝构造函数:拷贝构造函数的意义在于兼容C语言的初始化方式,用一个已经存在的对象来创建另一个新的对象,进而使得两个对象是一样的。
主要是为了兼容C语言的初始化方式,
主要是为了兼容C语言的初始化方式,
主要是为了兼容C语言的初始化方式,
重要的事情说三遍,构造函数的意义在于初始化

而赋值操作符重载的意义在于 赋值

一般涉及到申请对空间的情况下,我们需要同时提供 拷贝构造函数与赋值操作副重载函数

在这里插入图片描述

在这里插入图片描述

如果我们定义了一个空类,编译器会为我们自动填充以下函数,默认无参构造函数,默认拷贝构造函数,默认赋值操作符重载函数,析构函数。
在这里插入图片描述

在这里插入图片描述
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200202192603543.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xpbnV4QXJtYmlnZ29k,size_16,color_FFFFFF,t_70

待续。。。。。
待续。。。。。
待续。。。。。
待续。。。。。
待续。。。。。
待续。。。。。

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux老A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值