
实现字符串类,怎样设计拷贝、赋值、析构函数
字符串类的实现
拷贝、赋值、析构
- 拷贝构造(函数名称和类名相同),参数是自己。需要分配内存,将被拷贝的类的内存拷贝到分配的内存里
- 拷贝赋值:赋值,参数是自己。先自我赋值校验,通过后释放原来指向的内存,最后分配内存,将被拷贝的类的内存拷贝到分配的内存里
- 析构函数:释放指针指向的内存区域
赋值运算或者表达式返回值是引用
- 从两个问题来进行分析返回值问题和引用问题
1.首先,赋值表达式为什么要有返回值呢?为了支持链式的复制表达式!
1 | int a,b; |
其实是把b=1的返回值赋给了a,所以赋值表达式要有返回值。
2.为什么不返回值,而是返回引用呢?为了效率!
而且通常返回常量引用。比如你的赋值变量不是基本数据类型,而是对象时:
如果b=c返回的是值,则需要在=运算结束后,调用拷贝构造函数将结果复制为返回值(因为函数结束后栈空间是要被销毁的,而局部变量存储在栈空间中)。如果返回引用,则不需要调用复制返回值,直接将引用原有的变量。
编译器为类默认生成的这几个
1 | A() //默认构造函数 |
不同构造函数的调用时机
拷贝初始化 A y=x;//拷贝初始化,调用拷贝构造函数
直接初始化 A x(2);//直接初始化,调用构造函数
思路
1.存储的开辟和管理(需要一个指向字符串地址的指针,当前字符串的长度,当前字符串所开辟空间的长度在我看来至少需要这三个要素)
2.字符串本身基本概念的理解和设计
3.深拷贝和浅拷贝的实现和理解
4.拷贝函数、赋值函数、析构函数一般需要实现的功能
5.字符串是怎样被C++流给读取的和识别的,在自定义中如何实现(感觉这个涉及得更深一点就要到输入输出了)
6.特殊情况的处理(空指针和nullptr)
思考关键点:
code
1 | class String |
普通构造传的是指针
拷贝构造传的是引用
赋值函数传的是引用
首先了解形参:形参是实参额拷贝.
如果传值,那么形参会拷贝一份实参,用在对象上就是调用类的拷贝构造函数拷贝一个新的对象.
for example:
date (const date d1)//这里传的是值而不是引用.
//那么形参d1就会调用类的拷贝构造函数date(const date d1)
复制一份
// d1,现在这一层的d1又会再次调用拷贝构造函数,与刚才第一部的过程一致,
// 层层循环,无穷调用,导致程序崩溃.
3.那么传引用有什么用呢,首先要知道引用是什么,它是变量的别名,存变量的地址,通过它可以直接找到变量,然后直接对变量本身进行修改.如果传入一个对象的引用,那就不会调用它的拷贝构造函数.
1 | //普通构造函数 |
构造函数
构造函数的任务,就是初始化对象的数据成员,无论何时只要类的对象被创建,就会执行构造函数。
- 分类:
隐式创建/默认构造函数
显式创建/带参数的默认构造函数
1.默认的还好,主要就是涉及一个新空间的开辟是否是必须的问题(默认情况下是‘/0’状态还是nullptr状态)
2.如果是带参数的话,就是第一个是判断传入的参数是否是合法的,第二个就是处理传入的参数的相关内容
3.涉及到多种不同的带参形式的话,要对于所有可能传入的参数类型和组合进行分析,以便得出最优的参数设计组合