【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数

简介: 【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数

本节博客是对阅读剑指offer后的笔记归纳总结,有需要借鉴即可。


1.p21-p25内容概要

面试官对于语言的考察,主要有三种考察形式

  • 1.询问语法概念
  • 2.分析代码
  • 3.写代码

下面来依次进行举例(以cpp为例)并分析,对书中内容进行总结和提炼。

2.询问语法概念

常考:CPP关键字理解

举例:sizeof空类

问:定义一个空类型,里面没有任何函数和变量,其sizeof大小是多少?

答:非0,具体是多少取决于编译器。原因在于至少给一个字节标识该结构体的存在,从而能够去使用。

问:在该空类型中添加相对于的构造函数和析构函数,sizeof该类型是多大?为什么?

答:依旧是非0,原因在于构造函数和析构函数用到的是该类对象的地址,并且类中的函数是存放在内存的公共代码区的,并没有真的放在类对象中。如下图:

3.分析代码

举例:类中拷贝构造的无限递归问题

问:下面代码是否可以进行编译?其结果是什么?

class A
{
private:
int value;
piblic:
A(int n){value = n;}
A(A other) {value = other.value;}
void Print(){std::cout << value << std:endl;}
};
int _tmain(int arge,_TCHAR* argv[])
{
A a = 10;
A b = a;
b.Print();
return 0;
}

其实这个地方我感觉要看编译器怎么看待A(A other) {value = other.value;}该函数了。我自己在vs2022的环境下去测上面代码结果是10

如果编译器将其视为拷贝构造函数,那么编译是可以编过的,但是会陷入无限递归模式。

这是因为CPP语法规定值传参要调用拷贝构造进行拷贝。所以把a要先传给other就得调用拷贝构造,就会陷入无限递归模式。

如果编译器将其视为一般的构造函数重载,编译可以编过并且运行结果是10

这是因为编译器会因为没有拷贝构造而自动提供一份拷贝构造,虽然编译器提供的这个拷贝构造是浅拷贝,但在这个地方也足够用。

4.写代码

常考点:类内成员函数、迭代器

举例:string模拟实现的赋值运算重载

如下图为模拟string的类声明,请补充其赋值运算重载

下面直接给出一般答案,请思考其中的问题:

下面是对上面图片中的问题进行解答:

  • 1.返回类型string&:
  • 引用提高代码效率,引用不存在值拷贝调用拷贝构造问题
  • 返回string支持连续赋值,若为void则连续赋值会报错
  • 2.参数类型const string&
  • 引用提高代码效率
  • const限制str在函数内被修改
  • 3.if必要性
  • 具有必要性。
  • 可以防自赋值,提高代码效率
  • 在当前代码下,若无if,自赋值delete会把str和其本身全部delete,会变成空
  • 4.delete具有必要性
  • 防止内存泄漏长期影响服务器导致崩溃问题
  • 减少资源浪费

然而,虽然上面代码基本凑合,但是还有一个小问题,在特定场景下会出现崩溃。

异常安全性问题

当内存不足时,new char会抛异常,从而终止程序。
在上面代码中,会先删后创,如果发生new抛异常,会造成原string内容丢失

解决方案:

  • 方案1:将上面代码改为先创建新内容,再删除旧内容
  • 方案2:使用现代写法,即先创建一个临时string变量,再将其内容与*this进行交换
    下面是现代写法示例:

    实际上,这种现代写法本质就是一种代码复用

5.总结

本文主要是用三个例子讲了面试对语法的三种考察形式。

我感觉《剑指offer》这三个例子举得挺好,可以好好思考一波。


EOF

相关文章
|
3月前
|
Java
【Java基础面试三十一】、String a = “abc“; ,说一下这个过程会创建什么,放在哪里?
这篇文章解释了在Java中声明`String a = "abc";`时,JVM会检查常量池中是否存在"abc"字符串,若不存在则存入常量池,然后引用常量池中的"abc"给变量a。
|
3月前
|
Java
【Java基础面试三十二】、new String(“abc“) 是去了哪里,仅仅是在堆里面吗?
这篇文章解释了Java中使用`new String("abc")`时,JVM会将字符串直接量"abc"存入常量池,并在堆内存中创建一个新的String对象,该对象会指向常量池中的字符串直接量。
|
16天前
|
SQL Oracle 关系型数据库
[Oracle]面试官:你举例几个内置函数,并且说说如何使用内置函数作正则匹配
本文介绍了多种SQL内置函数,包括单行函数、非空判断函数、日期函数和正则表达式相关函数。每种函数都有详细的参数说明和使用示例,帮助读者更好地理解和应用这些函数。文章强调了字符串操作、数值处理、日期计算和正则表达式的使用方法,并提供了丰富的示例代码。作者建议读者通过自测来巩固学习成果。
14 1
[Oracle]面试官:你举例几个内置函数,并且说说如何使用内置函数作正则匹配
|
2月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
3月前
|
Java
【Java基础面试十一】、int和Integer有什么区别,二者在做==运算时会得到什么结果?
这篇文章解释了Java中`int`基本数据类型和其包装类`Integer`之间的区别,并指出在进行`==`运算时,`Integer`会拆箱为`int`类型,然后比较它们的值是否相等。
【Java基础面试十一】、int和Integer有什么区别,二者在做==运算时会得到什么结果?
|
3月前
|
Java
【Java基础面试二十六】、说一说String和StringBuffer有什么区别
这篇文章区分了Java中的String和StringBuffer类:String是不可变类,一旦创建字符序列就不能改变;而StringBuffer代表可变的字符串,可以通过其方法修改字符序列,最终可以通过`toString()`方法转换为String对象。
【Java基础面试二十六】、说一说String和StringBuffer有什么区别
|
3月前
|
Java API 索引
【Java基础面试二十四】、String类有哪些方法?
这篇文章列举了Java中String类的常用方法,如`charAt()`、`substring()`、`split()`、`trim()`、`indexOf()`、`lastIndexOf()`、`startsWith()`、`endsWith()`、`toUpperCase()`、`toLowerCase()`、`replaceFirst()`和`replaceAll()`,并建议面试时展示对这些方法的熟悉度,同时深入理解部分方法的源码实现。
【Java基础面试二十四】、String类有哪些方法?
|
2月前
|
JavaScript 前端开发
今天被JavaScript的String型和数字型的+运算撞了一下腰。
今天被JavaScript的String型和数字型的+运算撞了一下腰。
|
3月前
|
编译器 C++ 容器
【C++】String常见函数用法
【C++】String常见函数用法
|
3月前
|
JavaScript
【Vue面试题八】、为什么data属性是一个函数而不是一个对象?
这篇文章解释了为什么在Vue中组件的`data`属性必须是一个函数而不是一个对象。原因在于组件可能会有多个实例,如果`data`是一个对象,那么这些实例将会共享同一个`data`对象,导致数据污染。而当`data`是一个函数时,每次创建组件实例都会返回一个新的`data`对象,从而确保了数据的隔离。文章通过示例和源码分析,展示了Vue初始化`data`的过程和组件选项合并的原理,最终得出结论:根实例的`data`可以是对象或函数,而组件实例的`data`必须为函数。
【Vue面试题八】、为什么data属性是一个函数而不是一个对象?