繁体   English   中英

将 char 数组传递给需要 const std::string 引用的 function

[英]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;
}

上面的代码没有引起任何明显的问题,但如果有问题潜伏,我想更正它。 显然字符数组正在转换为字符串,但通过什么机制呢? 我想我有四个问题:

  1. 这个字符串是在堆栈上转换并通过引用传递还是通过值传递?
  2. 是否使用 operator= 重载? 一个“来自 c 字符串”的构造函数? 其他一些机制?
  3. 基于 2,这是否比使用构造函数显式转换为字符串效率低?
  4. 这危险吗。 :)

用 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 调用期间保持活动状态,并在返回时销毁。

考虑到所有这些,让我们解决您的问题:

  1. 它通过引用传递,但引用是临时的 object。
  2. 一个构造函数,因为我们正在构造一个 object.std std::string也有一个operator=接受一个const char*参数,但它从未用于隐式转换:你需要显式地分配一些东西。
  3. 由于运行相同的代码,性能是相同的,但是您确实会产生一些开销,因为复制数据而不是引用数据。 如果这是一个问题,请改用std::string_view
  4. 只要您不尝试保留参数的引用或指针超过 function 调用,这是安全的,因为 object 之后可能不存在(但您应该始终牢记引用参数)。 您还需要确保您传递的 C 字符串已正确终止 null。
  1. 这个字符串是否在堆栈上转换

该语言没有指定临时对象的存储,但在这种情况下它可能存储在堆栈中,是的。

还是按价值传递?

论点是一个参考。 因此,您是“通过引用”。

  1. 是否使用 operator= 重载?

不,你没有在那里使用 operator= ,那为什么呢?

一个“来自 c 字符串”的构造函数?

是的。

  1. 基于 2,这是否比使用构造函数显式转换为字符串效率低?

不会。object是隐式创建还是显式创建与效率无关。

然而,创建std::string的效率可能低于不创建它,您可以通过不接受对字符串的引用作为参数来实现。 您可以改用字符串视图。

  1. 这危险吗。

不是特别。 在某些情况下,当程序员没有注意到隐式转换时,隐式转换可能会导致一些问题,但通常它们会通过减少冗长来简化语言。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM