[英]Copy constructor and const
這是我遇到問題的代碼
class MyString {
char* str;
public:
MyString(const char* _str) : str(_str) {}
}
這是來自編譯器的錯誤消息
錯誤:從 'const char*' 到 'char*' 的無效轉換 [-fpermissive]
這是因為str
是char*
而_str
是const char*
嗎?
副本(我的意思是str(_str)
)是否應該是完全相同的類型(關於const
)?
我怎樣才能將此代碼修改為合理的代碼? 我想將MyString(const char* _str)
保留為const char*
。
簡短的回答:是的。
長答案: const char* str
是指向 memory 中包含 c 字符串的區域的指針。 通過將其標記為const
你是說它可能不會被改變。 您正在嘗試創建一個指向同一 memory 區域的新指針,但這個新指針表示該區域可能會更改,編譯器會抱怨這一點(因為原版說這是不允許的)。
請注意,您當前沒有將內容復制到字符串(我懷疑您想要),而是將指針復制到字符串。 要實際復制字符串,您必須首先分配 memory 然后復制內容。 或者只使用std::string
代替,它會為您管理所有這些。
是的,您不能將const char*
指針(指向 const 的指針)分配給char*
指針(指向非 const 的指針),它們不兼容。
如果您不介意您的 class 按原樣指向原始字符數據,那么您可以使str
成員成為指向 const 的指針:
class MyString {
const char* str;
public:
MyString(const char* _str) : str(_str) {}
};
您只需確保原始字符數據的壽命超過您的MyString
object。
這可能不是您想要的。 另一種選擇是讓您的 class 將字符數據復制到自身中:
class MyString {
char* str = nullptr;
public:
MyString(const char* _str) {
if (_str) {
str = new char[strlen(_str) + 1];
strcpy(str, _str);
}
}
...
};
請務必遵循3/5/0 規則來正確管理該副本。 這意味着實現一個析構函數來釋放副本,以及一個復制構造函數和復制賦值運算符來制作數據的副本,以及一個移動構造函數和移動賦值運算符來移動數據:
class MyString {
char* str = nullptr;
public:
MyString() = default;
MyString(const char* _str) {
if (_str) {
str = new char[strlen(_str) + 1];
strcpy(str, _str);
}
}
MyString(const MyString &src) : MyString(src.str) { }
MyString(MyString &&src) {
str = src.str;
src.str = nullptr;
}
~MyString() {
delete[] str;
}
MyString& operator=(MyString rhs) {
MyString tmp(std::move(rhs));
std::swap(src, tmp.src);
return *this;
}
};
更好的解決方案是改用std::string
,它會為您處理所有這些細節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.