一、如何区分自定义类与标准库中的同名类
// string.h
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include <iostream>
using namespace std;
namespace bit {
class string {
};
}
既然要模拟实现 string 底层,那就得先理解为什么我写的 string 和库 string 里面不会冲突。
1. 头文件查找路径
当我们用双引号 "" 包围头文件时,编译器会首先在当前目录下查找这个头文件。这意味着它会优先找到我们自己定义的头文件(比如 string.h),而不是标准库中的头文件。因为标准库的头文件通常在其他系统目录中,所以不会发生冲突。
2. 避免名字冲突
虽然使用双引号包含头文件可以让编译器优先使用我们自定义的头文件,但如果我们在头文件中定义了一个与标准库相同名称的类或函数,仍然可能导致混淆或冲突。
为了解决这个问题,我们可以使用命名空间。命名空间就像是一个独立的区域,把我们的代码和标准库的代码隔离开来。比如,我们创建一个 bit 命名空间,然后在这个命名空间里定义一个与标准库同名的类或函数,这样就可以避免冲突。
当我们在代码中使用这些定义时,需要明确指明是哪个命名空间下的。比如,使用 bit::string 来表示我们自定义的 string 类,而 std::string 则表示标准库中的 string 类。这样编译器就能清楚地区分它们。
二、构造 / 拷贝 / 析构函数
2.1 构造
2.1.1 空字符串构造函数(默认构造函数)
string() :_str(new char[1]), _size(0), _capacity(0) {
_str[0] = '\0';
}
在 std::string 类,空字符串的初始化会创建一个包含单个字符 ('\0') 的字符,用于表示字符串的结束。
那么 _str(new char[1]) 就是在堆上 new 一个包含 1 个 char 元素的数组。然后给这唯一的元素赋值 '\0'(赋值运算都是在构造函数体内进行)。
2.1.2 常量字符串构造函数
string(const char* str) : _str( [(str)]), _size((str)), _capacity((str)) {
(_str, str);
}


