从纯哲学的角度来看:是的,字符串是一种向量类型。它是一个连续的内存块,用于存储字符(向量是一个连续的内存块,用于存储任意类型的对象)。因此,从这个角度来看,字符串是一种特殊的向量。
在设计和实现 std::string
和 std::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 '\0' character
std::string
自C++11起将不再具有引用计数,因为许多实现所使用的写时复制功能已被C++11标准禁止。
从内存角度来看,std::string
实例与std::vector<char>
非常相似(例如它们都有指向其内存位置的指针、大小和容量),但两个类的功能是不同的。
std::string
与 std::vector
(以及其他标准容器)有部分接口是相同的,但它们是两个不同的东西,拥有不同的目的。
它们可能有非常不同的实现方式,因为 std::string
允许使用小字符串优化或写时复制(自2011年后已不再合法)。尽管它们可能具有非常相似的实现方式。
它们都支持随机访问迭代器,因此可以使用标准算法以类似的方式使用。我认为 std::string
不能被归类为序列容器。
很多 std::string
的成员函数不能直接通过从 std::vector
继承来实现,因为它隐藏了存储 NUL
终止符的事实。因此,当 std::string::size
返回 3
时,std::vector::size
将返回 4
,同样适用于 end
和其他一些函数。
string
到向量vector
的隐式转换是不允许的。例如,如果我编写这样的代码:int f(std::vector<char> const &s);
// ...
std::string s;
f(s);
f
重载)。std::vector
私有继承的方式来实现std::string
。虽然它可能不是最有效率的,但至少我无法想到它会明显违反什么要求。效率损失来自于std::vector
需要更加通用,因为它必须支持可以抛出异常的类型的实例化,而std::string
只设计用于可以免于异常的类型的实例化。std::vector<char>*
存储到 std::string
中,更不用说 delete
它了。 - BoBTFishstd::string
(std::basic_string<char>
)不是使用std::vector
实现的序列容器类型。你可以将其视为包含char
的序列容器之一,因为它与其他容器共享许多功能。
std::string
在所有实现中的行为保持一致。 基于写入时复制的实现需要考虑一些问题,而那些不尝试对字符串进行引用计数的实现则没有这些问题。 - Zac Howland