在我的C++项目中,我在更换所有内容之前迈出了一步char*,std::string但我发现某个特定场合std::string失败了.
想象一下,我有这两个功能:
void foo1(const std::string& s)
{
...
}
void foo2(const char* s)
{
...
}
Run Code Online (Sandbox Code Playgroud)
如果我写这样的东西:
const char* SL = "Hello to all!";
foo1(SL); // calls malloc, memcpy, free
foo2(SL);
Run Code Online (Sandbox Code Playgroud)
在foo1所述SL将隐式转换成std::string.这意味着std::string构造函数将分配内存,并将字符串文字复制到该缓冲区.在foo2虽然没有所有这些都不会发生.
在大多数实现std::string中应该是超级优化的(例如Copy On Write)但是当我用const char*它构造它时它不是.我的问题是:为什么会这样?我错过了什么吗?我的标准库是不是足够优化还是出于某种原因(我不知道)这是完全不安全的?
Mat*_* M. 21
实际上,如果你更改了文字,你的担忧就会消失(*):
std::string const SL = "Hello to all!";
Run Code Online (Sandbox Code Playgroud)
我const为你加了.
现在,呼叫foo1将不涉及任何复制(根本),并且foo2可以以很少的成本实现呼叫:
foo1(SL); // by const-reference, exact same cost than a pointer
foo2(SL.c_str()); // simple pointer
Run Code Online (Sandbox Code Playgroud)
如果要移动std::string,不仅要切换功能接口,还要切换变量(和常量).
(*)假设原始答案SL是全局常量,如果它是函数的局部变量,那么static如果真的希望避免在每次调用时构建它,则可以进行.
Kar*_*nek 10
问题是std :: string类无法识别const char*指针是否是全局字符文字:
const char *a = "Hello World";
const char *b = new char[20];
Run Code Online (Sandbox Code Playgroud)
char*指针可能在任何时候都无效(例如,当它是局部变量且函数/范围结束时),因此std::string必须成为字符串的独占所有者.这只能通过复制来实现.
以下示例说明了为什么有必要:
std::string getHelloWorld() {
char *hello = new char[64];
strcpy(hello, "Hello World");
std::string result = (const char *)hello; // If std::string didn't make a copy, the result could be a garbage
delete[] hello;
return result;
}
Run Code Online (Sandbox Code Playgroud)
std::string不是银弹.它旨在成为拥有其内存的通用可变字符串的最佳实现,并且使用C API相当便宜.这些是常见的场景,但它们与字符串使用的每个实例都不匹配.
正如您所提到的,字符串文字不适合这个用例.它们使用静态分配的内存,因此std::string不能也不应该尝试占用内存.并且这些字符串始终是只读的,因此std::string不允许您修改它们.
std::string 创建传递给它的字符串数据的副本,然后在内部处理此副本.
如果你想操作其生命周期在别处处理的常量字符串(在字符串文字的情况下,它由初始化和释放静态数据的运行时库处理),那么你可能想要使用不同的字符串表示.也许只是一个简单的const char*.
| 归档时间: |
|
| 查看次数: |
1470 次 |
| 最近记录: |