[英]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
不是內置類型。 這是一個類,可實現各種自定義行為,例如在對象復制上創建硬拷貝。
"some text" // this is a string literal, meaning the type is const char[num]
當您輸入字符串文字時,它很可能位於名為“ .rodata”的代碼的內部(只讀數據)。 您不能合法地修改此字符的值。 文本中還有一個“空終止符”-末尾的值為零的字符。 這很有用,因為您需要知道文字何時結束。 由於空終止符, num
始終number of characters
+1
。
當您編寫此代碼時:
const char* text = "hello world!";
// note that this is illegal:
// char* text = "hello world!"; // literal is read-only.
你只是說:
讓
text
指向文字所在的內存。
實際上,復制文本需要進行更多工作。 必須明確完成:
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 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[]
數組)。
當僅由其名稱引用時,定長數組會衰減為指向其第一個元素的指針。 因此,當它使用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&
(或當類重寫operator&
時使用std::addressof()
)來獲取對象的地址,則不能通過指針傳遞對象(除非它被分配了new
,在本例中不是這種情況) 。
如果你不希望傳遞的string
通過指針對象,你必須按引用傳遞它,而不是(否則,按值傳遞的對象將使得對象的副本,並且功能將不能修改原來的賓語):
void changeString(string &buffer) {
buffer = "test321";
}
string mystr;
changeString(mystr);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.