![](/img/trans.png)
[英]C++ passing argument of “struct” type as reference (&) or passing it by value
[英]C++ passing struct or object by value
我有這個:
enum Units { Pounds, Kilos };
struct Configuration
{
const Units units;
const char *name;
inline Configuration(Units pUnits, char *pName) : units(pUnits)
{
name = strdup(pName);
}
inline ~Configuration() { free((void *)name); }
};
我正在將其中一個傳遞給這樣的方法:
Configuration cc(Kilos, "abc");
cdao->write(cc);
我從這里得到了令人討厭的崩潰,直到我嘗試重新定義方法來引用:
Configuration cc(Kilos, "abc");
cdao->write(&cc);
現在一切正常。
但是,價值結構怎么可能與內存緊密相連?
您使用strdup的事實表明您的代碼有問題,而錯誤的是您沒有復制構造函數。 每當你有一個析構函數時,你幾乎肯定還需要一個復制構造函數,它會在你按值調用時正確復制對象。
要改進您的代碼:
創建一個復制構造函數,可能是一個賦值操作符,它正確地分配和復制字符串
更好的是,擺脫strdup - 使用std:;字符串,在這種情況下你不需要析構函數,復制ctor或賦值操作。
擺脫“內聯”關鍵字 - 他們什么都不做。
您沒有提供自己的復制構造函數或賦值運算符。 因此,當您進行復制或賦值時,將使用編譯器生成的復制構造函數和賦值運算符,在這種情況下實際上並不正確。 它們只是復制每個成員,因此您最終得到兩個引用相同字符數組的Configuration對象。 並且兩個Configuration對象都對刪除數組負責,這幾乎肯定會導致“雙刪除”錯誤。
請記住“ 三個規則 ”。 這里的問題是指針的行為不像你想要的那樣。 如果您使用了std :: string作為成員,則不必編寫自己的復制構造函數,析構函數,賦值運算符。 那是因為編譯器生成的那些只是調用其成員的相關操作,而字符串成員已經正確處理了這個 - 不像指向char的指針。
當你調用它的參考,它的復制units
和*name
而不是里面的值*name
。 因此,當該臨時對象被破壞時,它將從Configuration
所有實例中釋放*name
。
你必須添加你的struct一個復制構造函數並處理char * name; (意思是,分配和刪除內存,用值初始化)。
無論如何,對字符串使用char *是個好主意。 使用std :: string,它將為您處理一切。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.