stl - 字符串是向量

stl - Is a string a vector?

本文关键字:向量 字符串 stl      更新时间:2023-10-16

我在某个测验中遇到了一个问题"Is a string a vector? If yes, in what way? If no, why not?"他们都可以随机访问内容。但是字符串有一些向量没有的方法,它也可能有引用计数。所以很明显字符串不完全是一个向量(typedef字符串向量)是否有已知的实现class string : public vector <char>?如果没有 - 不实施它的原因是什么?

从纯粹的哲学角度来看:是的,字符串是一种向量。 它是存储字符的连续内存块(向量是存储任意类型对象的连续内存块)。 因此,从这个角度来看,字符串是一种特殊的向量。

std::stringstd::vector的设计和实现方面,它们共享一些相同的接口元素(例如连续的内存块,operator[]),但std::string不是std::vector派生的(旁注:你不应该公开从标准容器派生,因为它们不是设计为基于类的 - 例如,它们没有虚拟析构函数), 它们也不能直接相互转换。 也就是说,以下内容将无法编译:

std::string s = "abc";
std::vector<char> v = s; // ERROR!

但是,由于它们都支持迭代器,因此您可以将字符串转换为向量:

std::string s = "abc";
std::vector<char> v(s.begin(), s.end()); // note that the vector will NOT include the '' character

std::string将不再具有引用计数(截至 C++11),因为许多实现使用的写入时复制功能被 C++11 标准禁止。

从内存的角度来看,std::string 的实例看起来与std::vector<char>非常相似(例如,它们都有一个指向其内存位置、大小、容量的指针),但这两个类的功能是不同的。

std::string

接口中有一个与std::vector(和其他标准容器)相同的非平凡部分,但它绝对是不同的东西,具有不同的目的。

它的实现方式也可能非常不同,因为它允许诸如小字符串优化或写入时复制之类的事情(自2011年以来不合法)。(尽管它们肯定有可能具有非常相似的实现)。

它们都支持随机访问迭代器,因此可以以类似的方式与标准算法一起使用。我认为std::string不能归类为序列容器。

通过

继承std::vector不可能直接实现std::string成员函数,因为它隐藏了它也存储NUL终结者的事实。因此,当std::string::size返回3时,std::vector::size会返回4end和其他一些人也是如此。

不,std::stringstd::basic_string<char> ),您可以将其视为一种包含char的序列容器,因为它与其他容器共享许多功能,但它不是使用 std::vector 实现的。

它不能(或至少肯定不应该)使用公共继承实现的主要原因是不允许从stringvector的隐式转换。例如,如果我编写如下代码:

int f(std::vector<char> const &s);
// ...
std::string s;
f(s);

编译应该失败(没有接受string的其他f重载)。

如果你真的想,你可以(可能)使用std::vector的私有继承来合法地实现std::string。它可能没有尽可能高效,但至少是随手的,我想不出它明显违反的要求。效率的损失是由于std::vector需要更通用的事实 - 它必须支持对可能引发异常的类型进行实例化,而std::string仅设计为对无异常的类型进行实例化。