- 发帖可能变空内容,邪门暂不知所以然
- 『稷下学宫』新认证方式,24年网站打算和努力目标
主题:说说我前面提到过的面试题 -- 使用尽量中文
原题如下:
string s1("abcde"),s2("1234567"),s3;
s3=s1+s2; //now s3 should represent sth like "abcde1234567"
帖子后面给出了我的答案。当然好答案绝对不是唯一的,这里高手众多,希望大家能拨冗指正。
我对答案的评判有这么几个标准:
1. 知道基本的c++概念,类、构造析构、运算符重载,也知道必要的编程惯例,比如c风格的字符串。
2. 具有程序员级别的设计能力和问题解决能力,能根据简要的叙述设计出可行的实现框架。对问题中含糊或没有明确的部分,可以做出尽量合理的假设,并把这些假设体现在文档中。
3. 能够合理分配和释放资源,有RAII的概念。知道delelte[]和delete的区别。
4. 具备exception safe的概念。
5. 实现中避免常见的错误。知道一些避免错误的技巧。
6. 选择让代码的使用者不容易出错的实现方式。
7. 注意到一些易被忽略的实现细节,一个例子就是这道题里的字符串可能是双字节的或多字节的。
前6项都是比较基本和重要的。
我给出的答案里用了重载来实现编译时根据不同的类型调用不同版本的库函数,这个其实不很重要。大家可以忽略。
//myString.h
#ifndef MY_STRING_H
#define MY_STRING_H
#include <string.h>
#if _MSC_VER > 1000
#pragma warning(disable : 4996)
#endif
template<class T> //T could be char, wchar_t, unsigned char, specific to single character, wide character, or multibyte character string
class universal_string{
public:
universal_string();
universal_string(const T* source); //const is expected
virtual ~universal_string(); //virtual so that derived class would be deleted properly
universal_string(const universal_string<T>& source); //mandatory because of "rule of three"
universal_string<T>& operator =(const universal_string<T>& source);
size_t len() const{ //optional for this problem, good habit for a experienced programer though
return length;
}
//helper functions
universal_string<T>& concatenate(const universal_string<T>& source);
private:
size_t length; //we assume the longest string won't exceed an unsigned int.
T* pString;
};
template<class T> //allow expression like "AAA" + string2, in which the first operand is a pointer to char
const universal_string<T> operator + (const universal_string<T>& first, const universal_string<T>& second){ //first const here to make sure the expression won't be misused as lvalue.
universal_string<T> result(first);
return result.concatenate(second);
}
//following helper functions to decide which version function in library to call in compile time.
char * myStrCpy(char *strDestination,const char *strSource ){
return strcpy(strDestination,strSource);
}
wchar_t *myStrCpy( wchar_t *strDestination, const wchar_t *strSource){
return wcscpy(strDestination,strSource);
}
size_t myStrLen(const char* str){
return strlen(str);
}
size_t myStrLen(const wchar_t* str){
return wcslen(str);
}
#ifdef _MBCS
#include <mbstring.h>
unsigned char *myStrCpy(unsigned char *strDestination,const unsigned char *strSource ){
return _mbscpy(strDestination,strSource);
}
size_t myStrLen(const unsigned char* str){
return _mbslen(str);
}
#endif
template<class T>
universal_string<T>::universal_string(const T* source): //assume source is pointing to a valid string. especially, it can not be NULL
length(myStrLen(source)), //even we add codes to check if it is NULL, we still can not prevent it being some other non null but invalid value
pString(new T[length+1]){ //therefore such check does not make much sense.
myStrCpy(pString,source);
}
template<class T>
universal_string<T>::universal_string():
length(0),pString(new T[1]){ //T[1] instead of T to be compatible with destructor
*pString=0;
}
template<class T>
universal_string<T>::~universal_string(){
delete[] pString; //[] is mandatory
}
template<class T>
universal_string<T>::universal_string(const universal_string<T>& source):
length(source.length),
pString(new T[length+1]){
myStrCpy(pString, source.pString);
}
template<class T>
universal_string<T>& universal_string<T>::operator =(const universal_string<T>& source){
//your solution must gurantee that when
//1. source is *this, and/or
//2. exception is thrown inside the function
//it still handles correctly
T* buffer=new T[source.length+1];
myStrCpy(buffer,source.pString);
delete[] pString;
pString=buffer;
length=source.length;
return *this;
}
template<class T>
universal_string<T>& universal_string<T>::concatenate(const universal_string<T>& source){
//your solution must gurantee that when
//1. source is *this, and/or
//2. exception is thrown inside the function
if (source.length>0) {
size_t tmpLen=length+source.length;
T* buffer=new T[tmpLen+1];
if (pString!=NULL) myStrCpy(buffer,pString);
myStrCpy(buffer+length,source.pString); //since we know where to join, we use strcpy in stead of strcat for better performance
delete[] pString;
pString=buffer;
length=tmpLen;
}
return *this;
}
#define string universal_string<wchar_t>
#endif
//main.cpp
#include "myString.h"
int main(int narg,char**varg){
string s1(L"ABCDEFG"),s2(L"1234567"),s3;
s3=s1+s2;
}
本帖一共被 1 帖 引用 (帖内工具实现)
- 相关回复 上下关系6
🙂说说我前面提到过的面试题
🙂乱评一点答案 datudou 字1927 2010-09-26 01:21:20
🙂你这够复杂,面试的时候要写这么一个类,得花多少时间啊。 股市就是搏傻游 字0 2008-07-06 20:58:01
🙂其实如果熟练的话 使用尽量中文 字44 2008-07-06 21:03:52
🙂new分配内存失败是抛一个异常? 我记得当年好像也有返回NULL 股市就是搏傻游 字63 2008-07-06 21:25:34
🙂都有 使用尽量中文 字18 2008-07-06 21:31:57