9

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

4

4 回答 4

11

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

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

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

std::string通过继承来直接实现 的许多成员函数是不可能的,因为它隐藏了它还存储一个-terminatorstd::vector的事实。NUL例如,当std::string::size返回时3std::vector::size将返回4end和其他一些人也是如此。

于 2013-11-01T16:02:19.167 回答
10

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

在 和 的设计和实现方面std::string它们std::vector共享一些相同的接口元素(例如连续的内存块operator[],类 - 例如它们没有虚拟析构函数),它们也不能直接相互转换。也就是说,以下内容不会编译:std::stringstd::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 标准禁止。

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

于 2013-11-01T16:48:59.923 回答
3

不,std::string( std::basic_string<char>),你可以认为它是一种序列容器,char因为它与其他容器共享许多功能,但它不是使用std::vector.

于 2013-11-01T16:05:47.547 回答
3

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

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

// ...

std::string s;
f(s);

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

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

于 2013-11-01T16:32:44.233 回答