今天調試C++自定義String代碼的時候,碰到一個問題,編譯期報錯:對象包含與成員函數不兼容的類型限定符。
先看代碼:
class String { // 自定義String類
public:
String(const char *s)
{// 構造函數
if (!s) {
len = 0;
str = new char[1];
str[0] = 0;
}
else {
len = strlen(s);
str = new char[len + 1];
strcpy(str, s);
}
}
~String() { delete[] str; len = 0; } // 析構函數
int size() { return len; } // 字符個數
String& operator = (const String &s)
{ // 拷貝構造函數
if (this == &s) return *this;
delete[] str;
len = s.size();
str = new char[len + 1];
strcpy(str, s.c_str());
return *this;
}
const char *c_str()
{ // 獲得c風格字符串
return str;
}
private:
char *str;
int len;
};
int main()
{
String noun("book");
String verb = noun;
cout << noun.c_str() << endl;
cout << verb.c_str() << endl;
return 0;
}
MSVC 2017編譯器報錯信息:
E1086 對象含有與成員 函數 "String::size" 不兼容的類型限定符
E1086 對象含有與成員 函數 "String::c_str" 不兼容的類型限定符
問題出在哪里?
問題似乎出在operator =
中調用了String::size
和String::c_str
。
我們知道,operator =
左側表達式類內部成員是會被修改的,而右側表達式類內部是不會修改的,因此只能調用等號右側對象的const限定的函數(不是指const返回值),強制不能修改對象內部狀態。
解決辦法:在String::size
和String::c_str
函數上,加上const限定符:
class String {
public:
int size() const { return len; } // 添加了const限定符
String& operator = (const String &s)
{
if (this == &s) return *this;
delete[] str;
len = s.size();
str = new char[len + 1];
strcpy(str, s.c_str());
return *this;
}
const char *c_str() const // 添加了const限定符
{
return str;
}
...
};
...
總結:
- 拷貝構造函數中,只能調用當前類const限定函數;
- const限定的成員函數,只能調用const限定的成員函數,而不能調用非const限定的成員函數,即使沒有修改對象內部狀態;