本文学习自 狄泰软件学院 唐佐林老师的 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
待续。。。。。
待续。。。。。
待续。。。。。
待续。。。。。
待续。。。。。
待续。。。。。