Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::string声明的函数不抱怨返回字符*_C++_String - Fatal编程技术网

C++ std::string声明的函数不抱怨返回字符*

C++ std::string声明的函数不抱怨返回字符*,c++,string,C++,String,这不是我的计划,所以不要开始责骂我:-)。我得到了一些随机程序。MyFunc()正在返回全局声明的缓冲区。我使用VS2008,它不会抱怨 static char buffer[1024]; std::string MyFunc() { .... .... return buffer; } 但是,当我添加这行代码时 char * ret; ret = MyFunc() 它抱怨:“错误:不存在从“std::string”到“char*”的合适转换函数” 我的问题是为什

这不是我的计划,所以不要开始责骂我:-)。我得到了一些随机程序。MyFunc()正在返回全局声明的缓冲区。我使用VS2008,它不会抱怨

static char buffer[1024];

std::string MyFunc() {
    ....
    ....
    return buffer;
}
但是,当我添加这行代码时

char * ret;
ret = MyFunc() 
它抱怨:“错误:不存在从“std::string”到“char*”的合适转换函数”

我的问题是为什么编译器现在在抱怨?为什么语法检查中会出现这种变化?同样,我没有更改MyFunc()的自由。在我的程序中,如果我能

std::string ret;
ret = MyFunc(); 
摆脱语法错误,但我真的很想理解这种奇怪的行为

string()有一个接受char*的构造函数,因此可以自动进行转换。没有从字符串到字符*的自动转换。您必须调用string::c_str()来获取char*

编辑 尽管您只要求解释这种行为,但本论坛中的其他人似乎认为我没有提到string::c_str返回常量字符*,而不是简单字符*,这是对您的一点小小的改变。但解释仍然存在:没有从字符串到char*或const char*的隐式/自动转换。如果c_str对您很重要,请随意阅读。

string()有一个接受char*的构造函数,因此您可以自动进行转换。没有从字符串到字符*的自动转换。您必须调用string::c_str()来获取char*

编辑
尽管您只要求解释这种行为,但本论坛中的其他人似乎认为我没有提到string::c_str返回常量字符*,而不是简单字符*,这是对您的一点小小的改变。但解释仍然存在:没有从字符串到char*或const char*的隐式/自动转换。如果c_str对您很重要,请随意阅读。

编译器的不同行为不是因为语法,而是因为
std::string
的结构

当您从返回
std::string
的函数返回
char*
时,编译器注意到有一个
std::string
的构造函数,它接受
char*
,调用该构造函数,然后安静地返回结果

当您试图从
char*
-返回函数返回
std::string
时,编译器会尝试查看是否有转换运算符从
std::string
生成
char*
,发现没有此类运算符,并报告错误

如果要将字符串转换为
char*
,则需要复制字符串的缓冲区,如下所示:

char* ret_ch = new char[ret.size()+1];
memcpy(ret_ch, ret.c_str(), ret.size()+1);
return ret_ch;

您可能认为可以自行返回
c_str()
,但这不是一个好主意:“备份”此c字符串的缓冲区属于
std::string
对象,因此一旦字符串被释放,访问缓冲区就会开始产生未定义的行为。这就是为什么在访问字符串缓冲区时需要进行显式复制。当然,您还负责对复制的结果调用
delete[]

使编译器行为不同的不是语法,而是
std::string
的结构

当您从返回
std::string
的函数返回
char*
时,编译器注意到有一个
std::string
的构造函数,它接受
char*
,调用该构造函数,然后安静地返回结果

当您试图从
char*
-返回函数返回
std::string
时,编译器会尝试查看是否有转换运算符从
std::string
生成
char*
,发现没有此类运算符,并报告错误

如果要将字符串转换为
char*
,则需要复制字符串的缓冲区,如下所示:

char* ret_ch = new char[ret.size()+1];
memcpy(ret_ch, ret.c_str(), ret.size()+1);
return ret_ch;

您可能认为可以自行返回
c_str()
,但这不是一个好主意:“备份”此c字符串的缓冲区属于
std::string
对象,因此一旦字符串被释放,访问缓冲区就会开始产生未定义的行为。这就是为什么在访问字符串缓冲区时需要进行显式复制。当然,您还负责对复制的结果调用
delete[]

std::string
被设计为可从
char const*
隐式构造,因为它支持使用字符串文本和典型的C样式代码字符串作为初始值设定项

如果不支持这一点,那么只需要使用一些中间函数,这只会增加冗长和效率低下

然而,在另一个方向上,
std::string
故意设计为不隐式转换为
char const*
。部分原因可能是由于
std::string
在逻辑上是可变的,因此返回的原始指针只有在没有执行可能导致缓冲区替换或字符串破坏的操作时才有效。比如说,

    char const* s = foo().c_str();
其中,
foo
生成一个
std::string
,使
s
指向一个不再存在的缓冲区,一个无效的悬空指针

c_str()
成员函数调用使转换非常突出

考虑一下,如果一个人只写一篇文章,这个问题会变得多么普遍

    char const* s = foo();
并将其编译



关于删除的文本,我意识到字符串在逻辑上是可变的还是不可变的完全无关。很抱歉需要更多的咖啡

std::string
被设计为可从
char const*
隐式构造,因为它支持使用字符串文本和典型的C样式代码字符串作为初始值设定项值

如果不支持这一点,那么只需使用一些中间函数,这将添加n