簡體   English   中英

如何將const char *存儲到char *?

[英]How to store a const char* to a char*?

我有這個代碼按預期工作:

#define MAX_PARAM_NAME_LEN 32

const char* GetName()
{
    return "Test text";
}

int main()
{
    char name[MAX_PARAM_NAME_LEN];
    strcpy(name, GetName());    

    cout << "result: " << name << endl;
}

如果我想將結果存儲到char * (因為我正在使用的框架中的某些函數僅使用char *作為輸入)而不使用strcpy (為了代碼的實用性和可讀性,以及學習),怎么可能我做? 保持const ,這很好用:

const char* name;
name = GetName();

但我仍然有const

試圖只使用char*

char* name;
name = GetName();

invalid conversion from 'const char*' to 'char*' 這種轉換的最佳習慣是什么?

這種轉換的最佳習慣是在整個代碼中使用std::string 由於您使用的框架將const char*作為其輸入,因此您始終可以在std::string上傳遞c_str()調用的結果:

std::string GetName() {
    return "Test text";
}

int main() {
    std::string name = GetName();
    int res = external_framework_function(name.c_str());
    cout << "result: " << res << " for " << name << endl;
}

遙遠的第二好是在你的代碼中使用const char*

const char* name = GetName();

由於您使用的框架采用const char*您也很好。

如果需要非const指針,則無法復制字符串。 您可以為您創建一個功能,但您仍然有責任釋放您從中獲得的副本:

char* copy(const char* orig) {
    char *res = new char[strlen(orig)+1];
    strcpy(res, orig);
    return res;
}
...
char *name = copy(GetName());
...
delete[] name;

return "Test text"; 返回指向只讀字符串文字的指針。

如果您正在使用一個以char*作為輸入的const char* ,並且您有一個const char* (例如只讀字符串文字),那么您應該提供從該const char*開始的字符串的深層副本const char*這些功能。

否則,如果函數嘗試修改只讀字符串,則會在運行時冒未定義的行為。

你現在擁有的是足夠的; 假設您無法使用std::string (如果您可以使用std::string 並且所有框架函數都使用const char*輸入,那么我建議您重構代碼以使用std::string ,並傳遞c_str()方法的輸出那個字符串類到你的框架函數。)

最后,如果你的一些框架函數需要一個char*那么你總是可以自己構建一個小的適配器類:

class Adapter
{
public:
    Adapter(const& Adapter) = delete; /*don't try to copy me please*/
    Adapter& operator=(const Adapter& ) = delete; /*don't try to copy me please*/
    Adapter(const char* s) : m_s(::strdup(s))
    {
    }
    ~Adapter() /*free memory on destruction*/
    {
        ::free(m_s); /*use free to release strdup memory*/
    }
    operator char*() /*implicit cast to char* */
    {
        return m_s;
    }
private:
    char* m_s;
};

然后對於函數void foo(char* c) ,可以調用foo(Adapter("Hello"/*or any const char* */)); foo可以隨意嵌入匿名臨時的char* 您甚至可以增強此類以將構造函數轉換為char* ,在這種情況下,只會獲取指針的淺表副本(並且析構函數不會刪除內存)。

在C ++中,“刪除const ”的典型方法是使用const_cast<>

char *name = const_cast<char*>(GetName());

當然,這是不受歡迎的,丑陋的和潛在的危險,因為GetName()確實可以返回指向不應該更改的內容的指針,然后你去允許自己更改它。 在這種情況下,這是一個很難找到錯誤的好方法。

解決方法是使用std::string作為臨時保留區域; 這將意味着復制字符串,但這可能是性能可接受的:

std::string s(GetName());
char *name = s.c_str();

這當然只有在s超出范圍時不保留name時才有效。 如果是這種情況,那么您將擁有某種形式的持久性字符串存儲層。

你可以明確地施展它。 (char*) getName() 但你可能不應該這樣做。 因為const位意味着“承諾不改變它”。 所以如果我有一個函數void foo(const char* string)我正在說:“給我一個指向字符串的指針。我不會改變它。” 如果你聲明一個變量const char* string = "hello"; 你是說,不應該改變這個字符串。 因為你做出了這個承諾,編譯器知道,並且可以使你的代碼更有效率。 這就是為什么:

const char* a = "hello";
const char* b = "hello";
(a==b); //is probably true

你的編譯器知道你不會改變ab所以它使它們指向同一個地址,所以它只需要存儲一個"hello"字符串。 如果你現在要改變ab也會改變,這不是你想要的。

長話短說,如果你絕對確定你的調用函數沒有改變字符串,你可以明確地轉換它。 (或者更好的是,將函數更改為(const char*)如果它是你的)。
如果你不確定,你將不得不復制。 (就像你已經在使用strcpy() )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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