剑指Offer - 面试题1:赋值运算符函数

简介: 剑指Offer - 面试题1:赋值运算符函数

题目

如下为类型CMyString的声明,请为该类型添加赋值运算符函数。

class CMyString
{
public:
  CMyString(char* pData = nullptr);
  CMyString(const CMyString& str);
  ~CMyString(void);
private:
  char* m_pData;
};


分析

该代码并不难,但是有几个值得注意的点。

1、返回值声明为当前类型的引用,且返回自身的引用(*this)。目的是为了可以连续赋值.如:

CMyString str1,str2,str3;

str1 = str2 = str3;


2、传入参数的类型是否是常量引用。引用可以避免调用一次复制构造函数,能提高代码的效率,常量可以避免在赋值过程中改变传入的值。


3、是否释放实例自身已有的内存。如果不释放,然后赋值就会导致之前申请的那块内存彻底找不到了,造成内存泄漏。


4、(忽略的点)判断传入的参数和当前的实例(*this)是否为同一个实例(虽然这种情况少)。如果是就直接返回当前实例(*this)。如果我们不加以判断,先释放当前实例的内存,那么传入的参数指向的内存也就被释放了(因为俩者指向同一块内存),就找不到之前的值了。


代码如下

 CMyString& CMyString::operator=(const CMyString& str)
{
  //判断是否指向同一块地址
  if (this == &str)
  {
    return *this;
  }
  //释放自身
  delete[] m_pData;
  m_pData;
  //赋值
  int len = strlen(str.m_pData);
  m_pData = new char[strlen(str.m_pData) + 1];
  strcpy(m_pData, str.m_pData);
  //返回引用类型
  return *this;
}


思考:

这个代码还有一个问题,如果申请空间失败会怎么样?

内存不足导致new char抛出异常。先删除自身的值,然后新的空间开辟失败,得不到新的值。相当于我让你帮我办事情,事情没办好就算了,还把我给出卖了。


解决方法:我们可以通过一个临时对象来保存当前实例m_pData的地址,然后进行赋值,然后释放临时对象。

CMyString& CMyString::operator=(const CMyString& str)
{
  //判断是否指向同一块地址
  if (this != &str)
  {//交换str和strTemp的m_pData值
    CMyString strTemp(str);     //通过拷贝构造初始化strTemp
    char* pTemp = strTemp.m_pData;  //创建指针保存传入实例值的地址
    strTemp.m_pData = m_pData;    //将当前实例值的地址给到strTemp
  }//出了strTemp的作用后,自动调用strTemp的析构函数。
  return *this;
}

总结

越是简单的题,越要注意细节。考察的一些细微的处理。

本章完

目录
相关文章
|
13天前
|
SQL Oracle 关系型数据库
[Oracle]面试官:你举例几个内置函数,并且说说如何使用内置函数作正则匹配
本文介绍了多种SQL内置函数,包括单行函数、非空判断函数、日期函数和正则表达式相关函数。每种函数都有详细的参数说明和使用示例,帮助读者更好地理解和应用这些函数。文章强调了字符串操作、数值处理、日期计算和正则表达式的使用方法,并提供了丰富的示例代码。作者建议读者通过自测来巩固学习成果。
12 1
[Oracle]面试官:你举例几个内置函数,并且说说如何使用内置函数作正则匹配
|
3月前
|
机器学习/深度学习
【机器学习】如何判断函数凸或非凸?(面试回答)
文章介绍了如何判断函数是凸函数还是非凸函数,包括凸函数的定义、几何意义、判定方法(一元函数通过二阶导数判断,多元函数通过Hessian矩阵的正定性判断),以及凸优化的概念和一些经典的凸优化问题。
163 1
【机器学习】如何判断函数凸或非凸?(面试回答)
|
3月前
|
JavaScript
【Vue面试题八】、为什么data属性是一个函数而不是一个对象?
这篇文章解释了为什么在Vue中组件的`data`属性必须是一个函数而不是一个对象。原因在于组件可能会有多个实例,如果`data`是一个对象,那么这些实例将会共享同一个`data`对象,导致数据污染。而当`data`是一个函数时,每次创建组件实例都会返回一个新的`data`对象,从而确保了数据的隔离。文章通过示例和源码分析,展示了Vue初始化`data`的过程和组件选项合并的原理,最终得出结论:根实例的`data`可以是对象或函数,而组件实例的`data`必须为函数。
【Vue面试题八】、为什么data属性是一个函数而不是一个对象?
|
4月前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin中常见作用域函数
**Kotlin作用域函数概览**: `let`, `run`, `with`, `apply`, `also`. `let`安全调用并返回结果; `run`在上下文中执行代码并返回结果; `with`执行代码块,返回结果; `apply`配置对象后返回自身; `also`附加操作后返回自身
58 8
|
3月前
|
安全 编译器 C++
【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数
【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数
|
4月前
|
Android开发 Kotlin
Android面试题之kotlin中怎么限制一个函数参数的取值范围和取值类型等
在Kotlin中,限制函数参数可通过类型系统、泛型、条件检查、数据类、密封类和注解实现。例如,使用枚举限制参数为特定值,泛型约束确保参数为Number子类,条件检查如`require`确保参数在特定范围内,数据类封装可添加验证,密封类限制为一组预定义值,注解结合第三方库如Bean Validation进行校验。
76 6
|
3月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
6天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
8天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
27 4
|
1月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
66 2