C++ 通过引用传递字符串与通过引用传递字符数组
C++ pass string by reference vs pass char array by reference
好的,我是 C++ 的新手,我只是想问一下为什么您不应该使用“&”符号通过引用传递 char 数组,而应该使用字符串,因为两个参数都是指针。我写的示例代码:
void changeChar(char* buffer, int bSize) {
strcpy_s(buffer, bSize, "test123");
}
void changeString(string* buffer) {
*buffer = "test321";
}
char mychar[10] = "hello world";
string mystr;
changeChar(mychar, sizeof(mychar));
changeString(&mystr);
你需要知道,std::string
不是 built-in 类型。它是一个 class,可实现所有类型的自定义行为,例如在对象复制时创建硬拷贝。
"some text" // this is a string literal, meaning the type is const char[num]
当您输入字符串文字时,它很可能位于名为“.rodata”(只读数据)的代码部分内。您不能合法修改此字符的值。文本还有一个 "null terminator" - 末尾值为零的字符。它很有用,因为您需要知道文字何时结束。 num
总是 number of characters
+1
,因为空终止符。
当你这样写的时候:
const char* text = "hello world!";
// note that this is illegal:
// char* text = "hello world!"; // literal is read-only.
你只要说:
let text
point to the memory, where the literal is located.
复制文本实际上需要更多的工作。必须明确地完成:
char* notReadOnly = new char[30]; // you can allocate some more
// program will still interpret character of value 0 as the end, even if buffer is bigger
std::strcpy(notReadOnly, "hello world");
// use string literal as src in std::strcpy
请注意,您也需要手动删除它:
delete[] notReadOnly;
std::string
让它变得容易多了。当你这样写时,它会自动复制文本:
std::string text = "some string literal";
std::string
的复制构造函数也制作缓冲区的硬拷贝。即使 std::string
class 看起来像这样:
class string
{
char *buffer;
std::size_t numberOfCharacters;
};
每次复制时,它都会执行 buffer
的硬拷贝,看起来像这样:
class string
{
// rest
string(const string &other)
{
numberOfCharacters = other.numberOfCharacters;
buffer = new char[numberOfCharacters];
// copy everything
std::strncpy(buffer, other.buffer, numberOfCharacters);
}
};
请注意,这只是一个简化的示例。
std::string a = "some text";
std::string b = a; // copy constructor is called. It uses method implemented above
const char* x = "some text2";
const char* y = x; // copy constructor is called. Only the address is copied, there is no hard copy of the actual buffer.
当您将变量作为参数传递给函数时,也会调用复制构造函数。但是在某些常见情况下,编译器可以对其进行优化。
changeChar()
将 char*
指针指向内存中 某处 的 char
(该函数假定 char*
是实际上指向指定大小的 char[]
数组。
一个 fixed-length 数组 衰减 为指向其第一个元素的指针,当仅通过其名称引用时。因此,当需要 char*
指针时,不需要(您也不能)使用 operator&
将 mychar[]
数组传递给 changeChar()
函数。
如果你不想通过指针传递 mychar
,你必须通过引用传递它(否则,通过值传递它会复制数组,然后函数将不会'无法修改原始数组)。在这种情况下,编译器可以为您推断出数组大小:
template<size_t size>
void changeChar(char (&buffer)[size]) {
strcpy_s(buffer, size, "test123");
}
char mychar[] = "hello world";
changeChar(mychar);
changeString()
将 string*
指针指向内存中 某处 的 string
对象。
如果不使用 operator&
(或当 class 覆盖 operator&
时 std::addressof()
)获取对象的地址(除非它是用 new
分配的,在你的例子中不是这种情况。
如果您不想通过指针传递 string
对象,则必须通过引用传递它(否则,通过值传递对象将复制该对象,并且函数将无法修改原始对象):
void changeString(string &buffer) {
buffer = "test321";
}
string mystr;
changeString(mystr);
好的,我是 C++ 的新手,我只是想问一下为什么您不应该使用“&”符号通过引用传递 char 数组,而应该使用字符串,因为两个参数都是指针。我写的示例代码:
void changeChar(char* buffer, int bSize) {
strcpy_s(buffer, bSize, "test123");
}
void changeString(string* buffer) {
*buffer = "test321";
}
char mychar[10] = "hello world";
string mystr;
changeChar(mychar, sizeof(mychar));
changeString(&mystr);
你需要知道,std::string
不是 built-in 类型。它是一个 class,可实现所有类型的自定义行为,例如在对象复制时创建硬拷贝。
"some text" // this is a string literal, meaning the type is const char[num]
当您输入字符串文字时,它很可能位于名为“.rodata”(只读数据)的代码部分内。您不能合法修改此字符的值。文本还有一个 "null terminator" - 末尾值为零的字符。它很有用,因为您需要知道文字何时结束。 num
总是 number of characters
+1
,因为空终止符。
当你这样写的时候:
const char* text = "hello world!";
// note that this is illegal:
// char* text = "hello world!"; // literal is read-only.
你只要说:
let
text
point to the memory, where the literal is located.
复制文本实际上需要更多的工作。必须明确地完成:
char* notReadOnly = new char[30]; // you can allocate some more
// program will still interpret character of value 0 as the end, even if buffer is bigger
std::strcpy(notReadOnly, "hello world");
// use string literal as src in std::strcpy
请注意,您也需要手动删除它:
delete[] notReadOnly;
std::string
让它变得容易多了。当你这样写时,它会自动复制文本:
std::string text = "some string literal";
std::string
的复制构造函数也制作缓冲区的硬拷贝。即使 std::string
class 看起来像这样:
class string
{
char *buffer;
std::size_t numberOfCharacters;
};
每次复制时,它都会执行 buffer
的硬拷贝,看起来像这样:
class string
{
// rest
string(const string &other)
{
numberOfCharacters = other.numberOfCharacters;
buffer = new char[numberOfCharacters];
// copy everything
std::strncpy(buffer, other.buffer, numberOfCharacters);
}
};
请注意,这只是一个简化的示例。
std::string a = "some text";
std::string b = a; // copy constructor is called. It uses method implemented above
const char* x = "some text2";
const char* y = x; // copy constructor is called. Only the address is copied, there is no hard copy of the actual buffer.
当您将变量作为参数传递给函数时,也会调用复制构造函数。但是在某些常见情况下,编译器可以对其进行优化。
changeChar()
将 char*
指针指向内存中 某处 的 char
(该函数假定 char*
是实际上指向指定大小的 char[]
数组。
一个 fixed-length 数组 衰减 为指向其第一个元素的指针,当仅通过其名称引用时。因此,当需要 char*
指针时,不需要(您也不能)使用 operator&
将 mychar[]
数组传递给 changeChar()
函数。
如果你不想通过指针传递 mychar
,你必须通过引用传递它(否则,通过值传递它会复制数组,然后函数将不会'无法修改原始数组)。在这种情况下,编译器可以为您推断出数组大小:
template<size_t size>
void changeChar(char (&buffer)[size]) {
strcpy_s(buffer, size, "test123");
}
char mychar[] = "hello world";
changeChar(mychar);
changeString()
将 string*
指针指向内存中 某处 的 string
对象。
如果不使用 operator&
(或当 class 覆盖 operator&
时 std::addressof()
)获取对象的地址(除非它是用 new
分配的,在你的例子中不是这种情况。
如果您不想通过指针传递 string
对象,则必须通过引用传递它(否则,通过值传递对象将复制该对象,并且函数将无法修改原始对象):
void changeString(string &buffer) {
buffer = "test321";
}
string mystr;
changeString(mystr);