- 前引
- C++ 经典基础面试题:string类的基础设计
- 1、题目(原型代码)
- 1、String::String(const char* str) 构造函数
- 2、String::String(const String& other) 拷贝构造函数
- 3、String::~String 析构函数
- 4、String& String::operator= (const String& other) 赋值函数
- 5、String String::operator+ (const String& other) 字符串相加
- 6、bool String::operator==(const String& other) const 判断是否为相同字符串
- 7、int String::GetLength() const 返回字符串长度
- 2、总代码 + 测试代码
前引
刚刚看了一下 一本关于后台开发知识点的总结的书
感觉写的挺糟糕的 大部分东西都是抄的网上的 还是腾讯员工写的
但是作为知识点补足看看还是ok的
里面有个关于C++的很经典的考察基础的面试题 就是string类的基础设计
觉得挺有趣的 想自己写写 于是就写下了这篇博客
大概率后面 博客会越发越少了 因为确实之后也没什么可以发的了 目前我所做的 基本上该做的也全做了 最多之后目前我能想的到的 也就是找到实习后 再做做 MIT关于分布式系统的那个Lab
因为说实话 到现在对于目前我的阶段 除了为实习面试准备 再查缺补补漏 也好像确实没啥可以做的了 前引部分就先写到这里
C++ 经典基础面试题:string类的基础设计
1、题目(原型代码)
下面是原型题目 接下来需要编写 也就是补足String的7个函数
成员没有size
代码风格是用的google style 自从之前完成了项目 之后代码风格统一采用google style 固定住自己的代码风格也很重要 当然这和这道题没有关系 只是我顺口提了一嘴
class String {
public:
String(const char* str = NULL);
String(const String& other);
~String();
String& operator= (const String& other);
String operator+ (const String& other);
bool operator== (const String& other);
int GetLength() const;
private:
char* m_data_;
};
1、String::String(const char* str) 构造函数
在看了答案前 主要我没有考虑到 如果进来是NULL
如果传进来是NULL的话 我们的strlen就会直接报错 因为我们需要保证strlen传进来的参数是non-null 这个也是我刚刚去试了一下才发现的
需要考虑的是 最后一位 由于是最后一位设置为 是自古一来判断字符串是否已经走到了最后的判断方法 所以我们需要设置额外的一个char空间来存放
String::String(const char* str) {
if (str == NULL) {
m_data_ = new char[1];
m_data_[0] = ' ';
return;
}
int length = strlen(str);
m_data_ = new char[length + 1];
memcpy(m_data_, str, length);
m_data_[length] = ' ';
}
2、String::String(const String& other) 拷贝构造函数
这里的话 依然需要注意一下 就是对方的是否为null
其他的就没了
String::String(const String& other) {
if (!other.m_data_) {
m_data_ = new char[1];
m_data_[0] = ' ';
}
int length = strlen(other.m_data_);
m_data_ = new char[length + 1];
memcpy(m_data_, other.m_data_, length);
m_data_[length] = ' ';
}
3、String::~String 析构函数
这里很简单 需要delete一下即可
只是m_data_ 又初始化为NULL 这个可能算个加分点 一个delete后的字符串不再使用 delete后立马设置为NULL
String::~String() {
if (m_data_) {
delete m_data_;
m_data_ = NULL;
}
}
4、String& String::operator= (const String& other) 赋值函数
这个需要稍微看一下 是否为NULL 其他的就是需要在之前先把我们分配的空间给delete掉
最重要的是 在开始判断是否是相同的指针 相同的地址空间
如果是的话 直接返回当前对象即可 不需要任何操作
String& String::operator= (const String& other) {
if (other.m_data_ != m_data_) {
if (m_data_ != NULL) {
delete m_data_;
}
if (other.m_data_ == NULL) {
m_data_ = NULL;
} else {
int length = strlen(other.m_data_);
m_data_ = new char[length + 1];
memcpy(m_data_, other.m_data_, length);
m_data_[length] = ' ';
}
}
return *this;
}
5、String String::operator+ (const String& other) 字符串相加
这个的话 就需要一个额外的临时对象了
如果相连接的是NULL的话 就直接拷贝当前对象返回就好了
其他的就是正常操作了
String String::operator+ (const String& other) {
String newstring;
if (other.m_data_ == NULL) {
newstring = *this;
} else {
int nowlength = strlen(m_data_);
int otherlength = strlen(other.m_data_);
int length = nowlength + otherlength;
newstring.m_data_ = new char[length + 1];
memcpy(newstring.m_data_, m_data_, nowlength);
memcpy(newstring.m_data_ + nowlength, other.m_data_, otherlength);
newstring.m_data_[length] = ' ';
}
return newstring;
}
6、bool String::operator==(const String& other) const 判断是否为相同字符串
这个工作交给strcmp即可 没什么其他的
bool String::operator==(const String& other) const {
return strcmp(m_data_, other.m_data_) == 0 ? true : false;
}
7、int String::GetLength() const 返回字符串长度
由于我们没有成员int size_ 其实正常的应该是有的 但是我们按照题目来吧 有的话 可以不用每次都strlen 工作交给strlen即可
但是注意 有可能存在NULL的情况 则需要先判断一下
int String::GetLength() const {
if (m_data_ == NULL) {
return 0;
}
return strlen(m_data_);
}
2、总代码 + 测试代码
下面就是测试正确性的代码了
包括上面的所有的代码
为了方便检查正确 我还重载了<< 方便os输出
就写到这里了 去做核酸了
#include#include #include using namespace std; class String { public: String(const char* str = NULL); String(const String& other); ~String(); String& operator= (const String& other); String operator+ (const String& other); bool operator== (const String& other) const; friend ostream& operator<< (ostream& os, const String& str); int GetLength() const; private: char* m_data_; }; String::String(const char* str) { if (str == NULL) { m_data_ = new char[1]; m_data_[0] = ' '; return; } int length = strlen(str); m_data_ = new char[length + 1]; memcpy(m_data_, str, length); m_data_[length] = ' '; } String::String(const String& other) { if (!other.m_data_) { m_data_ = new char[1]; m_data_[0] = ' '; } int length = strlen(other.m_data_); m_data_ = new char[length + 1]; memcpy(m_data_, other.m_data_, length); m_data_[length] = ' '; } String::~String() { if (m_data_) { delete m_data_; m_data_ = NULL; } } String& String::operator= (const String& other) { if (other.m_data_ != m_data_) { if (m_data_ != NULL) { delete m_data_; } if (other.m_data_ == NULL) { m_data_ = NULL; } else { int length = strlen(other.m_data_); m_data_ = new char[length + 1]; memcpy(m_data_, other.m_data_, length); m_data_[length] = ' '; } } return *this; } String String::operator+ (const String& other) { String newstring; if (other.m_data_ == NULL) { newstring = *this; } else { int nowlength = strlen(m_data_); int otherlength = strlen(other.m_data_); int length = nowlength + otherlength; newstring.m_data_ = new char[length + 1]; memcpy(newstring.m_data_, m_data_, nowlength); memcpy(newstring.m_data_ + nowlength, other.m_data_, otherlength); newstring.m_data_[length] = ' '; } return newstring; } bool String::operator==(const String& other) const { return strcmp(m_data_, other.m_data_) == 0 ? true : false; } int String::GetLength() const { if (m_data_ == NULL) { return 0; } return strlen(m_data_); } ostream& operator<< (ostream& os, const String& str) { return os << str.m_data_; } int main() { String str(NULL); cout << "str(NULL) str : " << str << endl; String tmp("gogo"); cout << "tmp("gogo") "tmp : " << tmp << endl; cout << "str == tmp : " << (str == tmp ? "true" : "false") << endl; String emptystring(NULL); cout << "str == emptystring : " << (str == emptystring ? "true" : "false") << endl; str = tmp; cout << "str = tmp str : " << str << endl; String tmpstring = str + tmp; cout << "tmpstring = str + tmp tmpstring : " << tmpstring << endl; cout << "str == tmp : " << (str == tmp ? "true" : "false") << endl; cout << "str == tmpstring : " << (str == tmpstring ? "true" : "false") << endl; return 0; }



