gpt4 book ai didi

c++ - std::string(char* char_array) 是如何实现的?

转载 作者:行者123 更新时间:2023-11-30 02:41:16 26 4
gpt4 key购买 nike

我很想知道字符串类如何实现从字符数组复制以初始化其内容。

我的猜测是这样的:

1:查找字符数组的长度,N。(这是怎么做到的?粗略的方法是单独查看每个字符,直到找到空字符?是否使用更好的方法?)

2:分配N个字节的存储。

3:使用strcpy逐字节复制每个元素。

显然这不是一个非常复杂的问题,我只是想知道以下是否(本质上或近似地)等价:

std::string program_name(argv[0]);

std::string program_name;
int length = 0;
while(*(argv[0] + length) != '/0')
++ length;
++ length; // Depends on whether string contains the null character - usually I don't think it does?
program_name.resize(length); // Maybe use reserve instead?
std::cpy(program_name.data(), argv[0], length - 1); // Don't copy the null character at the end

反正就是这样。我没有尝试编译上面的伪代码,因为我感兴趣的是方法的概念,而不是这个操作如何完成的细节。

最佳答案

简而言之,您的实现几乎就是它的工作原理。

忽略 std::string 是从 std::basic_string 实现的事实,它被模板化以处理存储在字符串中的各种数据类型(特别是“宽字符” "), std::string 来自 char * 的构造函数可以这样写:

std::string(const char* init_value)
{
size_t m_len = strlen(init_value);
char *m_storage = new char[m_len+1];
std::copy(m_storage, init_value, m_len+1);
}

当然,由于实际实现的继承和模板化特性,实际实现会更加间接[可能具有特定功能来“增长/分配”,例如]。

这是 libcxx 的真实实现:

template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
{
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
__init(__s, traits_type::length(__s));
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
}

__init 执行此操作的位置:

template <class _CharT, class _Traits, class _Allocator>
void
basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_type __sz)
{
if (__sz > max_size())
this->__throw_length_error();
pointer __p;
if (__sz < __min_cap)
{
__set_short_size(__sz);
__p = __get_short_pointer();
}
else
{
size_type __cap = __recommend(__sz);
__p = __alloc_traits::allocate(__alloc(), __cap+1);
__set_long_pointer(__p);
__set_long_cap(__cap+1);
__set_long_size(__sz);
}
traits_type::copy(_VSTD::__to_raw_pointer(__p), __s, __sz);
traits_type::assign(__p[__sz], value_type());
}

它做了一些技巧来将值存储在指针中[并使用相关的分配器分配,它可能不是new],并显式初始化结束标记[traits_type::assign (__p[__sz], value_type());,因为对 __init 的调用可能会使用与 C 样式字符串不同的参数,因此不能保证结束标记。

traits_type::length()strlen

template <>
struct _LIBCPP_TYPE_VIS_ONLY char_traits<char>
{
...
static inline size_t length(const char_type* __s) {return strlen(__s);}
....
};

当然,其他STL实现可能会使用不同的细节实现,但大致是作为我的简化示例,但更加混淆以应对多种类型和重用代码。

关于c++ - std::string(char* char_array) 是如何实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28263922/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com