当前位置: 首页 > news >正文

MyString类的常见面试问题

MyString类 – 面试问题总结

针对以下代码总结常见面试问题

#include<iostream>#include<cstring>usingnamespacestd;classMyString{private:char*p;public:MyString(){p=newchar[1];p[0]='\0';}MyString(constchar*str){p=newchar[strlen(str)+1];strcpy(p,str);}MyString(constMyString&S){p=newchar[strlen(S.p)+1];strcpy(p,S.p);}~MyString(){delete[]p;}MyString&operator=(constchar*str){if(p==str)return*this;delete[]p;p=newchar[strlen(str)+1];strcpy(p,str);return*this;}MyString&operator=(constMyString&S){if(this==&S)return*this;delete[]p;p=newchar[strlen(S.p)+1];strcpy(p,S.p);return*this;}friendostream&operator<<(ostream&os,constMyString&S){os<<S.p;returnos;}MyStringoperator+(constMyString&S)const{MyStringtemp(p);strcat(temp.p,S.p);returntemp;}MyStringoperator+(constchar*str)const{MyStringtemp(str);return*this+temp;}friendMyStringoperator+(constchar*str,constMyString&S){MyStringtemp(str);returntemp+S;}MyString&operator+=(constchar*str){*this=*this+str;return*this;}char&operator[](intidx){returnp[idx];}charoperator[](intidx)const{returnp[idx];}MyStringoperator()(intstart,intlen){intsize=strlen(p);if(start<0||start>=size)returnMyString{};intactualLen=start+len-1<size?len:size-start;char*str=newchar[actualLen+1];strncpy(str,p+start,actualLen);str[actualLen]='\0';MyStringtemp(str);delete[]str;returntemp;}booloperator>(constMyString&S)const{returnstrcmp(p,S.p)>0;}booloperator<(constMyString&S)const{returnstrcmp(p,S.p)<0;}booloperator==(constMyString&S)const{returnstrcmp(p,S.p)==0;}};/* qsort()自定义比较函数 */intCompareString(constvoid*e1,constvoid*e2){constMyString*s1=(constMyString*)e1;constMyString*s2=(constMyString*)e2;if(*s1>*s2)return1;elseif(*s1<*s2)return-1;elsereturn0;}intmain(){MyStrings1("abcd-"),s2,s3("efgh-"),s4(s1);MyString SArray[4]={"big","me","about","take"};cout<<"1. "<<s1<<s2<<s3<<s4<<endl;s4=s3;s3=s1+s3;cout<<"2. "<<s1<<endl;cout<<"3. "<<s2<<endl;cout<<"4. "<<s3<<endl;cout<<"5. "<<s4<<endl;cout<<"6. "<<s1[2]<<endl;s2=s1;s1="ijkl-";s1[2]='A';cout<<"7. "<<s2<<endl;cout<<"8. "<<s1<<endl;s1+="mnop";cout<<"9. "<<s1<<endl;s4="qrst-"+s2;cout<<"10. "<<s4<<endl;s1=s2+s4+" uvw "+"xyz";cout<<"11. "<<s1<<endl;qsort(SArray,4,sizeof(MyString),CompareString);for(inti=0;i<4;i++)cout<<SArray[i]<<endl;//s1的从下标0开始长度为4的子串cout<<s1(0,4)<<endl;//s1的从下标5开始长度为10的子串cout<<s1(5,10)<<endl;return0;}

1. 你在 MyString 类中定义了私有成员 char* p ,为什么要使⽤动态内存分配?不动态分配(⽐如⽤固定数组)会有什么问题?

1)使用动态内存分配:

  • 可以灵活地根据字符串长度分配内存空间,避免了内存溢出或造成内存大量浪费

2)使用固定数组:

  • 长度受限:字符串过长会造成内存溢出、程序崩溃;字符串过短会大量内存浪费
  • 无法灵活地进行赋值/拼接:固定数组不能扩容/缩容,赋值拼接操作失效
  • 对象体积臃肿:每一个对象都会携带一个固定长度的字符数组,内存占用极高

2. 什么是浅拷贝?什么是深拷贝?你的MyString类是如何全面实现深拷贝的?请结合你写的代码说明。

3. 什么是 C++ 的三 / 五法则?你的类符合这个法则吗?

三法则(C++98)

当一个类需要手写析构函数时,必须同时实现:

  1. 析构函数
  2. 拷贝构造函数
  3. 拷贝赋值运算符
  • 目的:避免浅拷贝造成内存泄漏、重复释放等问题
五法则(C++11)

在三法则的基础上必须添加两个移动操作:

  1. 移动拷贝函数
  2. 移动赋值运算符
  • 目的:支持高效转移临时对象资源,提升性能
我的类实现了三法则,但是没有两个移动操作,没有避免对临时对象深拷贝带来的开销
//===================//对临时对象的移动拷贝//===================MyString(MyString&&S)noexcept//告诉编译器不会抛异常{p=S.p;//偷临时对象的指针S.p=nullptr;//临时对象置为空,delete []nullptr;完全安全}
//===================//对临时对象的移动赋值//===================MyString&operator=(MyString&&S)noexcept//告诉编译器不会抛异常{if(this==&S)//避免自赋值return*this;delete[]p;p=S.p;//偷临时对象的指针S.p=nullptr;//临时对象置为 nullptrreturn*this;}

4. 你写的const char*版本的赋值运算符里的自赋值判断if(p == str),你觉得有问题吗?

5.你实现的赋值运算符 ( operator= ), 为什么要先判断 this == &S ? 不判断会有什么问题?结合代码说明。

6.你的代码中, operator+ 返回值是 MyString , ⽽ operator+= 返回值是 MyString& , 为什么要这样设计?两者的区别是什么?

7.operator<< (输出运算符) 为什么必须重载为友元函数,⽽不能作为MyString 类的成员函数?结合代码说明。

8.你的代码中,为什么要提供 “const char* + MyString” 的全局友元operator+ ? 成员函数 operator+ 不能实现吗?

9.operator () 在这⾥实现什么功能?为什么可以像函数⼀样调⽤?

10. 为什么析构要⽤ delete [] ⽽不是 delete ?

11.qsort 为什么需要你写 CompareString ⽐较函数?

12.你实现的operator+运算符,有没有发现缓冲区溢出的问题?

13.为什么要实现两个版本的赋值运算符重载?

14.为什么要给operator[]实现两个版本?

15.比较运算符后面的const是什么意思?为什么要加?

16.为什么 qsort 的比较函数要写成全局函数?不能写成类的成员函数吗?

17.为什么用strncpy之后还要手动加’\0’?

18.你的析构函数不是虚函数,这会带来什么问题?

19.你的operator+=的实现有没有可以优化的地方?

20.你将成员函数operator+声明为const是为了什么?

21.你为C语言的库函数 qsort() 写的比较函数 CompareString 传入的指针类型是 const void* , 你能结合代码说一下将 const void* 转换为 const MyStirng* 有什么具体的变化吗?

22. 可以把自己写的无参构造函数去掉,用C++默认的吗?

23. 你的类现在支持移动语义吗?怎么添加?有什么好处?

24. 你了解小字符串优化(SSO)吗?你的类可以怎么用它来优化?

25. 什么是拷贝和交换惯用法?用它来实现赋值运算符有什么好处?

26. 你了解写时复制(COW)吗?为什么现在很少用了?

27. 赋值运算符为什么要返回MyString&引用?不能返回值吗?

28. 你实现的赋值运算符重载还可能存在什么风险?你能聊一聊Copy and Swap吗?

RAII

1. 你了解 RAII 吗?你能默写出 RAII 的英文全称吗?你的 MyString 类是不是用到了 RAII?

2. 如果不用 RAII,手动管理这个字符串的内存,会有什么问题?

3. 你的 MyString 类的拷贝操作,和 RAII 有什么关系?

4. RAII 只能用来管理堆内存吗?

http://www.jsqmd.com/news/609899/

相关文章:

  • 破解GitHub访问难题:Fast-GitHub 3大核心引擎实现开源项目访问加速
  • Claude Code fileHistory 文件编辑快照与回滚机制深度解析
  • Python 数据处理封神篇:CSV+JSON 全解析,从入门到天气 API 实战
  • 别再只用threshold了!Halcon二值化8大算子保姆级对比(附实战避坑指南)
  • 六种AI驱动的文献引用生成策略在学术研究中的高效应用
  • 【信息科学与工程学】【管理科学】第十六篇 利益设计与分配:从静态薪酬到动态激励生态系统的工程化重构
  • 面向法律文书 Agent 的 Harness 条款冲突检测
  • HJ168 小红的字符串
  • Kali+PHPStudy搭建红日靶场:那些教程里没提的玄学问题解决方案
  • 状态对写题很重要
  • React倒计时终极方案:时间对齐+面试必考
  • 【RWA 机制,ERC-4626,ERC-3643,ERC-7540,ERC-7575,LayerZero】
  • 2026降AI率工具实测:SpeedAI科研小助手为什么是首选?
  • 小红书合规引流新姿势:聚光平台落地页卡片制作全流程指南
  • 40岁程序员未裸辞!AI赋能后,我的月薪从6k涨到6.07万,行业真相曝光!
  • 阿姆智创15.6寸工控电脑一体机,源头工厂ODM定制方案,赋能工业产线与机器视觉设备场景
  • 编译即优化:Cuvil在Llama-3-8B本地推理中的延迟压降至127ms,你还在用原生torch.compile?
  • Python数据分析如何重置索引_Pandas的reset_index应用
  • 计算机毕业设计:Python全国空气质量与气象监测平台 Flask框架 可视化 数据分析 机器学习 天气 深度学习 AI 空气质量分析(建议收藏)✅
  • 深入解析MCU:从哈佛架构到智能家居应用
  • 深度可分离卷积
  • CC2530开发入门:用IAR EW8051和SmartRF Flash Programmer烧录第一个Zigbee程序
  • 为什么你的API吞吐量卡在8k QPS?Span<T> + MemoryPool<T>组合拳让Kestrel直冲23k QPS(附压测报告)
  • 头歌实战 3-3 MongoDB 复杂条件查询与数据聚合技巧
  • 从OSG牛模型变黑说起:深入GL3渲染模式与Ubuntu 20.04下的图形开发环境调优
  • 双轴卷取分切机程序,PLC和触摸屏使用西门子smart200系列。 前后卷取双轴张力控制计算
  • eNSP启动AR报错码40终极排查指南:从Hyper-V冲突到虚拟网卡修复
  • IDEA+Maven环境下SuperMap iDesktopX二次开发避坑指南(附完整配置流程)
  • 别再让图片拖慢你的多模态模型了:手把手教你用Q-Former和PruMerge压缩视觉Token(附代码)
  • 避开STC8A8K64S4A12的ADC那些坑:配置寄存器、结果对齐与电压跟随器详解