我在某个测验中遇到了一个问题"Is a string a vector? If yes, in what way? If no, why not?
"他们都可以随机访问内容。但是字符串有一些向量没有的方法,它也可能有引用计数。所以很明显字符串不完全是一个向量(typedef字符串向量)是否有已知的实现class string : public vector <char>
?如果没有 - 不实施它的原因是什么?
从纯粹的哲学角度来看:是的,字符串是一种向量。 它是存储字符的连续内存块(向量是存储任意类型对象的连续内存块)。 因此,从这个角度来看,字符串是一种特殊的向量。
在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 ' ' 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
会返回4
。end
和其他一些人也是如此。
不,std::string
( std::basic_string<char>
),您可以将其视为一种包含char
的序列容器,因为它与其他容器共享许多功能,但它不是使用 std::vector
实现的。
它不能(或至少肯定不应该)使用公共继承实现的主要原因是不允许从string
到vector
的隐式转换。例如,如果我编写如下代码:
int f(std::vector<char> const &s);
// ...
std::string s;
f(s);
编译应该失败(没有接受string
的其他f
重载)。
如果你真的想,你可以(可能)使用std::vector
的私有继承来合法地实现std::string
。它可能没有尽可能高效,但至少是随手的,我想不出它明显违反的要求。效率的损失是由于std::vector
需要更通用的事实 - 它必须支持对可能引发异常的类型进行实例化,而std::string
仅设计为对无异常的类型进行实例化。