博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[GeekBand] C++ 基础知识之 The Big Three
阅读量:6888 次
发布时间:2019-06-27

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

本文是GeekBand课程体系中,侯捷老师讲课内容的部分内容总结。

参考书籍如下:Effitive C++ 

                   C++ Primer 第五版

                   http://blog.csdn.net/lwbeyond/article/details/6202256 中的部分图片

一定义:C++  三大函数

构造函数:如 : String(const char* cstr = 0);

拷贝构造函数 如 :String(const String& str);

拷贝赋值函数 如 :String& operator=(const String& str);

析构函数:如 :~String();

 

其中,拷贝构造函数、拷贝赋值函数、析构函数被称为C++ 的三大函数!

 

下面以String类进行分析:

1 class String 2 { 3 public: 4     String(const char* cstr = 0); 5     String(const String& str); 6     String& operator=(const String& str); 7     ~String(); 8     char* get_c_str() const { return m_data; } 9 private:10     char* m_data;11 };

 

二、实现:

    如果上面定义看起来还不够直观,那么从调用函数角度再看下:

String s2("world");  // 构造函数    String s3(s2);       //拷贝构造函数    s3 = s1;             // 拷贝赋值函数,左边的值给右边,所以称为赋值

 

      通过上面的分析,我们从形式上看到了三种构造函数的区别。当然如果程序员没写这些代码,程序也会自动生成这些代码~当然自动生成的代码,有时会有所缺陷。下面

仔细分析下各个地方所需要注意的知识要点。

0、构造函数相关知识点

1、构造函数中不带指针的情况

     这种情况比较简单,只需要赋给参数的初值即可!一般系统自带生成的构造函数都可以实现。

2、构造函数中如果带有指针的情况

     以代码String类为参考。那么每次输入的字符串如何保存呢?可能会想到利用数组,那么则会碰到另外一个问题,那就是数组要多大才合适?

     比如说保存“hello”、"helloworld".......字符串的长度每次都不是固定的,这里可以采用两种方法解决!

     一、利用动态数组去完成,二、利用指针去完成。相对来说,指针更灵活一些。所以这里采用指针,而且STL库里也是采用指针的方法去完成的

    那么指针是如何确定字符串大小的呢?

    这里也有两种方法,一种是指针指向头部,利用结束符'\0'进行判断

    另一种第一个字符保存长度大小,后面指针指向实际数据即可。

 

1、拷贝构造函数相关知识点

这里面采用了  http://blog.csdn.net/lwbeyond/article/details/6202256 中的部分图片。

 

原始数据,一个指针指向了数据

浅拷贝:拷贝的只是指针,这种情况下会出现各种问题!

深拷贝:

如果拷贝构造

 

如果拷贝构造函数中不含指针的话,那么编译器会自动生成拷贝构造函数,既看,只会一位、一位的进行赋值操作。所以此时采用系统默认的情况即可

 

但如果拷贝构造函数中含有指针,指针也是4个字节的数据,如果还才有一位一位的进行赋值,这样,拷贝过来的指针就会与原指针指向同一个地方。既浅拷贝。

所以如果类中有指针,我们采用的自己写的构造函数,这时对应的便是深拷贝!

 

1 inline2 String::String(const String& str)3 {4     m_data = new char[strlen(str.m_data) + 1];5     strcpy(m_data, str.m_data);6 }

 

这里采用String (const String &str),说明它只接受 “它自己这样的东西” 所以我们采用new 先创建一个空间大小可以保持复制过来的数据

然后再赋给数据即可

(PS:new 这里面也是采用malloc 进行开辟空间的)

2、拷贝赋值函数相关知识点

 

首先观察下String类的拷贝赋值函数

1 inline 2 String& String::operator=(const String& str) 3 { 4     if (this == &str) 5         return *this; 6  7     delete[] m_data; 8     m_data = new char[strlen(str.m_data) + 1]; 9     strcpy(m_data, str.m_data);10     return *this;11 }

 

通过观察 把S2 = S1,实际上就是完成操作符重载的过程(operator+)如下:

1、先删除S2自己本身的内存;

2、然后重新分配一块与S1大小相同的内存;

3、再把S1的内容拷贝到S2上即可。

~~满满的都是套路~~

那么判断 this 与&str 是什么东西?为什么要这么做?

简单的思考就是,节省效率吗,单并不是主要原因,下面采用侯捷老师课程中的资料解释下:清晰明了!

 

 

3、析构函数相关知识点

 

inlineString::~String(){    delete[] m_data;}

 

一般来说,会隐式的自动调用析构函数,所以很多情况下不必写出来。

然而,如果有指针,还是要自动进行释放掉,否则会引起内存泄露等问题。

 

析构函数中还对应着继承、委托等各种情况下的析构顺序等,这些留着下篇进行分享。

              

                          ————以上这些均来自GeekBand,侯捷老师授课内容。侯捷老师具有丰富的C++知识,听课后收获很大。

                                                                                                                          By NiceCoder

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/xuhe/p/5726388.html

你可能感兴趣的文章
Linux三剑客之一awk
查看>>
3.第一个Java程序
查看>>
linux系统优化
查看>>
2018-1-17 Linux学习笔记(awk)[重要]
查看>>
rinetd端口转发
查看>>
test2
查看>>
26期20180619 lvm讲解
查看>>
子网划分
查看>>
HDFS体系结构简介及优缺点
查看>>
Spring Boot - 构建RESTful API与单元测试
查看>>
Rust 基础: 变量与常量区别
查看>>
Spring事务管理及基本事务属性
查看>>
javaweb 文件blob上传到数据库以及反显
查看>>
ListView在开发中的小技巧
查看>>
怎么将图片中的水印去掉,去水印工具有什么
查看>>
尚思卓越运维风险管理系统
查看>>
iphone/ipad前端开发技巧
查看>>
我的Linux系统开始学习的过程
查看>>
DHCP
查看>>
10-17 课程笔记
查看>>