MyString类的常见面试问题

张开发
2026/6/12 6:03:13 15 分钟阅读
MyString类的常见面试问题
MyString类 – 面试问题总结针对以下代码总结常见面试问题#includeiostream#includecstringusingnamespacestd;classMyString{private:char*p;public:MyString(){pnewchar[1];p[0]\0;}MyString(constchar*str){pnewchar[strlen(str)1];strcpy(p,str);}MyString(constMyStringS){pnewchar[strlen(S.p)1];strcpy(p,S.p);}~MyString(){delete[]p;}MyStringoperator(constchar*str){if(pstr)return*this;delete[]p;pnewchar[strlen(str)1];strcpy(p,str);return*this;}MyStringoperator(constMyStringS){if(thisS)return*this;delete[]p;pnewchar[strlen(S.p)1];strcpy(p,S.p);return*this;}friendostreamoperator(ostreamos,constMyStringS){osS.p;returnos;}MyStringoperator(constMyStringS)const{MyStringtemp(p);strcat(temp.p,S.p);returntemp;}MyStringoperator(constchar*str)const{MyStringtemp(str);return*thistemp;}friendMyStringoperator(constchar*str,constMyStringS){MyStringtemp(str);returntempS;}MyStringoperator(constchar*str){*this*thisstr;return*this;}charoperator[](intidx){returnp[idx];}charoperator[](intidx)const{returnp[idx];}MyStringoperator()(intstart,intlen){intsizestrlen(p);if(start0||startsize)returnMyString{};intactualLenstartlen-1size?len:size-start;char*strnewchar[actualLen1];strncpy(str,pstart,actualLen);str[actualLen]\0;MyStringtemp(str);delete[]str;returntemp;}booloperator(constMyStringS)const{returnstrcmp(p,S.p)0;}booloperator(constMyStringS)const{returnstrcmp(p,S.p)0;}booloperator(constMyStringS)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};cout1. s1s2s3s4endl;s4s3;s3s1s3;cout2. s1endl;cout3. s2endl;cout4. s3endl;cout5. s4endl;cout6. s1[2]endl;s2s1;s1ijkl-;s1[2]A;cout7. s2endl;cout8. s1endl;s1mnop;cout9. s1endl;s4qrst-s2;cout10. s4endl;s1s2s4 uvw xyz;cout11. s1endl;qsort(SArray,4,sizeof(MyString),CompareString);for(inti0;i4;i)coutSArray[i]endl;//s1的从下标0开始长度为4的子串couts1(0,4)endl;//s1的从下标5开始长度为10的子串couts1(5,10)endl;return0;}1. 你在 MyString 类中定义了私有成员 char* p 为什么要使⽤动态内存分配不动态分配⽐如⽤固定数组会有什么问题1使用动态内存分配可以灵活地根据字符串长度分配内存空间避免了内存溢出或造成内存大量浪费2使用固定数组长度受限字符串过长会造成内存溢出、程序崩溃字符串过短会大量内存浪费无法灵活地进行赋值/拼接固定数组不能扩容/缩容赋值拼接操作失效对象体积臃肿每一个对象都会携带一个固定长度的字符数组内存占用极高2. 什么是浅拷贝?什么是深拷贝你的MyString类是如何全面实现深拷贝的请结合你写的代码说明。3. 什么是 C 的三 / 五法则你的类符合这个法则吗三法则(C98)当一个类需要手写析构函数时必须同时实现析构函数拷贝构造函数拷贝赋值运算符目的避免浅拷贝造成内存泄漏、重复释放等问题五法则(C11)在三法则的基础上必须添加两个移动操作移动拷贝函数移动赋值运算符目的支持高效转移临时对象资源提升性能我的类实现了三法则但是没有两个移动操作没有避免对临时对象深拷贝带来的开销////对临时对象的移动拷贝//MyString(MyStringS)noexcept//告诉编译器不会抛异常{pS.p;//偷临时对象的指针S.pnullptr;//临时对象置为空delete []nullptr;完全安全}////对临时对象的移动赋值//MyStringoperator(MyStringS)noexcept//告诉编译器不会抛异常{if(thisS)//避免自赋值return*this;delete[]p;pS.p;//偷临时对象的指针S.pnullptr;//临时对象置为 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吗RAII1. 你了解 RAII 吗你能默写出 RAII 的英文全称吗你的 MyString 类是不是用到了 RAII2. 如果不用 RAII手动管理这个字符串的内存会有什么问题3. 你的 MyString 类的拷贝操作和 RAII 有什么关系4. RAII 只能用来管理堆内存吗

更多文章