我想通過使用 std::strings 將我們遺留代碼庫中使用 cstrings 的靜態資料結構轉換為動態資料結構。問題是,現在,在我們的代碼庫中調整所有使用它們的函式是不可行的。
我建議使用一個包裝類(屬性代理模式),它在內部使用 std::string 公開一個 cstring API。這將允許使用 cstring 函式(strcpy、strlen、memset 等)并使資料結構向后兼容。這是我到目前為止所擁有的:
原始資料結構:
struct data
{
char property1[20];
char property2[20];
}
新結構:
struct data
{
CStringProperty property1;
CStringProperty property2;
}
包裝類:
class CStringProperty
{
public:
CStringProperty(){}
CStringProperty(std::string& value) : _value{value}{}
CStringProperty(char* value) : _value{value}{}
CStringProperty& operator=(std::string value)
{
_value = value;
return *this;
}
CStringProperty& operator=(char* value)
{
std::string valueStr = value;
return operator=(valueStr);
}
operator std::string()
{
return _value;
}
operator char*()
{
return &_value[0];
}
char& operator[](int i)
{
return _value[i];
}
std::string to_str()
{
return _value;
}
private:
std::string _value;
friend std::ostream& operator<<(std::ostream& os, CStringProperty& value);
};
std::ostream& operator<<(std::ostream& os, CStringProperty& value)
{
return os << value.to_str();
}
測驗
int main()
{
CStringProperty a= "Hello";
std::cout << "Test 1: " << a << std::endl; // Works
CStringProperty b;
b = a;
std::cout << "Test 2: " << b << std::endl; // Works
CStringProperty c;
char d[10] = "Hello";
c = d;
std::cout << "Test 3: " << c << std::endl; // Works
char* e = a;
std::cout << "Test 4: " << e << std::endl; // Works
CStringProperty f;
std::cout << "Test 5: " << f << std::endl; // Works
CStringProperty g = "Hello";
g[0] = 'X';
std::cout << "Test 6: " << g << std::endl; // Works
CStringProperty h = "Hello";
std::cout << "Test 7: " << std::to_string(strlen(h)) << std::endl; // Works
CStringProperty p = "hello";
strcpy(p,"bye");
std::cout << "Test 8.1: " << std::to_string(strlen(p)) << std::endl; // Works
std::cout << "Test 8.2: " << p << std::endl; // Doesn't work
CStringProperty q;
strcpy(q,"bye");
std::cout << "Test 9.1: " << std::to_string(strlen(q)) << std::endl; // Works
std::cout << "Test 9.2: " << q << std::endl; // Doesn't work
return 0;
}
我知道 std::string::data() 暴露了底層的 cstring,但這會回傳 a const char*,所以它顯然只是為了閱讀目的。使用const_castI supose 與我在上面所做的類似,并導致未定義的行為。
如果知道沒有辦法做到這一點,我會非常沮喪,因為這將意味著真正巨大的重構作業,所以我感謝任何幫助或想法。
uj5u.com熱心網友回復:
9.2和8.2之所以不行,是因為std::string有size_資料成員。strcpy函式不會修改它。
您可以使用friend函式(或常規函式)來解決此問題。
class CStringProperty
{
public:
CStringProperty(){}
CStringProperty(std::string const& value) : _value{value}{}
CStringProperty(char const* value) : _value{value}{}
CStringProperty& operator=(std::string value)
{
_value = value;
return *this;
}
CStringProperty& operator=(char* value)
{
std::string valueStr = value;
return operator=(valueStr);
}
operator std::string()
{
return _value;
}
operator char const*()
{
return _value.c_str();
}
char& operator[](int i)
{
return _value[i];
}
private:
std::string _value;
friend std::ostream& operator<<(std::ostream& os, CStringProperty const& value)
{
return os << value._value;
}
friend void strcpy(CStringProperty& value, char const* src)
{
value._value = src;
}
friend size_t strlen(CStringProperty const& value)
{
return value._value.size();
}
};
另一個問題是您不在const需要的地方使用。而且您還std::string按值傳遞,這可能會影響性能。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/426974.html
