我在一些测验中遇到了一个问题“ Is a string a vector? If yes, in what way? If no, why not?
”他们都可以随机访问内容。但是字符串有一些向量不使用的方法。它也可能有引用计数。所以很明显 string 不完全是一个向量(typedef string vector) 是否有已知的实现class string : public vector <char>
?如果不是 - 不这样做的原因是什么?
4 回答
std::string
它的接口与std::vector
(和其他标准容器)有一个共同的部分,但它绝对是不同的东西,具有不同的目的。
它也可能以非常不同的方式实现,因为它允许小字符串优化或写时复制(自 2011 年以来不合法)之类的事情。(尽管它们当然有可能具有非常相似的实现)。
它们都支持随机访问迭代器,因此可以以与标准算法类似的方式使用。我认为 std::string
不能归类为序列容器。
std::string
通过继承来直接实现 的许多成员函数是不可能的,因为它隐藏了它还存储一个-terminatorstd::vector
的事实。NUL
例如,当std::string::size
返回时3
,std::vector::size
将返回4
。end
和其他一些人也是如此。
从纯哲学的角度来看:是的,字符串是一种向量。它是一个存储字符的连续内存块(向量是一个存储任意类型对象的连续内存块)。所以,从这个角度来看,字符串是一种特殊的向量。
在 和 的设计和实现方面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 标准禁止。
从内存的角度来看,一个 的实例看起来与astd::string
非常相似std::vector<char>
(例如,它们都有一个指向其内存位置、大小、容量的指针),但是这两个类的功能是不同的。
不,std::string
( std::basic_string<char>
),你可以认为它是一种序列容器,char
因为它与其他容器共享许多功能,但它不是使用std::vector
.
它不能(或至少肯定不应该)使用公共继承实现的主要原因是不应允许从string
to的隐式转换。vector
例如,如果我编写如下代码:
int f(std::vector<char> const &s);
// ...
std::string s;
f(s);
编译应该失败(没有其他f
接受 a 的重载string
)。
如果你真的想要,你可以std::string
(可能)做一个使用私有继承的合法实现std::vector
。它可能不是尽可能高效,但至少是临时的,我想不出它明显违反的要求。效率的损失将是由于std::vector
需要更通用的事实 - 它必须支持对可以引发异常的类型进行实例化,而std::string
仅设计为对无异常的类型进行实例化。