![](/img/trans.png)
[英]passing a const char instead of a std::string as function argument
[英]Passing a char array to a function that expects a const std::string reference
我在前一段时间写的套接字接口中犯了一个错误,我只是在查看代码以解决另一个问题时才注意到这个问题。 socket接收到一串字符,传给jsoncpp完成json的解析。 我几乎可以理解这里发生的事情,但我无法理解它。 我想了解引擎盖下实际发生的事情。 这是最小的例子:
#include <iostream>
#include <cstring>
void doSomethingWithAString(const std::string &val) {
std::cout << val.size() << std::endl;
std::cout << val << std::endl;
}
int main()
{
char responseBufferForSocket[10000];
memset(responseBufferForSocket, 0, 10000);
//Lets simulate a response from a socket connection
responseBufferForSocket[0] = 'H';
responseBufferForSocket[1] = 'i';
responseBufferForSocket[2] = '?';
// Now lets pass a .... the address of the first char in the array...
// wait a minute..that's not a const std::string& ... but hey, it's ok it *works*!
doSomethingWithAString(responseBufferForSocket);
return 0;
}
上面的代码没有引起任何明显的问题,但如果有问题潜伏,我想更正它。 显然字符数组正在转换为字符串,但通过什么机制呢? 我想我有四个问题:
用 g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609 编译
std::string
有一个非显式构造函数(即没有用explicit
关键字标记),它采用const char*
参数并复制字符直到第一个'\0'
(如果字符串中不存在这样的字符,则行为未定义)。 换句话说,它执行源数据的副本。 这是此页面上的超载#5 。
const char[]
隐式衰减为const char*
,您可以将临时值传递给 function 并采用const
引用参数。 顺便说一句,这仅在引用为const
时才有效; 如果你不能使用const
,按值传递它。
因此,当您将const char[]
传递给 function 时,将使用该构造函数构造一个std::string
类型的临时 object,并绑定到参数。 临时对象将在 function 调用期间保持活动状态,并在返回时销毁。
考虑到所有这些,让我们解决您的问题:
std::string
也有一个operator=
接受一个const char*
参数,但它从未用于隐式转换:你需要显式地分配一些东西。std::string_view
。
- 这个字符串是否在堆栈上转换
该语言没有指定临时对象的存储,但在这种情况下它可能存储在堆栈中,是的。
还是按价值传递?
论点是一个参考。 因此,您是“通过引用”。
- 是否使用 operator= 重载?
不,你没有在那里使用 operator= ,那为什么呢?
一个“来自 c 字符串”的构造函数?
是的。
- 基于 2,这是否比使用构造函数显式转换为字符串效率低?
不会。object是隐式创建还是显式创建与效率无关。
然而,创建std::string
的效率可能低于不创建它,您可以通过不接受对字符串的引用作为参数来实现。 您可以改用字符串视图。
- 这危险吗。
不是特别。 在某些情况下,当程序员没有注意到隐式转换时,隐式转换可能会导致一些问题,但通常它们会通过减少冗长来简化语言。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.