簡體   English   中英

C ++通過引用傳遞字符串vs通過引用傳遞char數組

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM