[英]C++ String class implementation
我的項目要求在 C++ 中實現字符串 class,但是,我對公共 function 之一感到困惑
class String
{
private:
char* buffer;
int size;
public:
// Initializes a string to be empty (i.e., its length will
// be zero and toChars() will return "").
String();
// Initializes a string to contain the characters in the
// given C-style string, which is assumed to be null-terminated.
String(const char* chars);
// Initializes a string to be a copy of an existing string,
// meaning that it contains the same characters and has the
// same length.
String(const String& s);
// Destroys a string, releasing any memory that is being
// managed by this object.
~String() noexcept;
};
除了String(const char* chars);
function,我都正確實現了它們,但我對如何實現這一點沒有任何線索。
編輯:由於不能使用 c++ 標准庫,我必須不使用strlen()
來計算chars
的大小
String::String(){
size = 0;
buffer = nullptr;
}
String::String(const char* chars){
int i = 0;
for (char* p = chars;*p != '\0'; p++){
++i;
}
size = i;
buffer = new char[size+1];
i = 0;
for(;i<size;i++){
buffer[i] = chars[i];
}
buffer[i] = '\0';
}
String::String(const String& s){
size = s.size;
buffer = new char[size];
for int(i=0;i<size;i++){
buffer[i] = s.buffer[i];
}
}
String::~String() noexcept{
delete[] buffer;
}
您應該使用std::vector<char>
作為緩沖區,這樣您就不會顯式調用new[]
和delete[]
。 std::vector
是 C++ 的一部分(並且已經存在了很長時間),所以這肯定是“在 C++ 中實現 [ing] 字符串 class ......”(並且不使用std::string
)
class String final
{
std::vector<char> buffer;
public:
String() = default;
String(const char* chars){
auto begin = chars;
auto end = begin + strlen(chars);
buffer.insert(buffer.begin(), begin, end);
}
String(const String& s){
buffer = s.buffer;
}
~String() = default;
};
注意現在各種構造函數有多簡單。 這具有避免內存泄漏和異常安全的額外優勢; 並且您甚至不必(幾乎)考慮這些問題。
如果你真的想避免使用std::vector
(為什么?它非常適合這種情況),那么至少你應該使用std::unique_ptr<char[]>
(或者可能是std::shared_ptr<char[]>
) 添加到 C++11。
class String final
{
std::unique_ptr<char[]> buffer;
public:
String() = default;
~String() = default;
String(const String&) = delete;
String& operator=(const String&) = delete;
String(const char* chars) {
const auto len = strlen(chars);
buffer = std::make_unique<char[]>(len + 1);
strcpy(buffer.get(), chars);
}
};
您最近的編輯沒有多大意義。 從strlen()
可以看出,即使是看似“簡單”的 function 也很難做到正確; 這就是我們有標准庫的原因。 如果您不能使用任何標准庫,那么甚至沒有任何方法可以動態分配 memory ,就像使用malloc()
完成的那樣。
您分配的 memory 數量存在一些差異,它們會回來咬你。
size + 1
char
s。size
char
s。 我建議您在各處分配size + 1
為 null 終結器留出空間。 這也將使實現評論示例中提到的toChars()
function 變得非常容易:
char* String::toChars() { return buffer; }
由於您不允許使用任何標准庫函數,例如std::strlen()
或std::memcpy()
,並且由於您可能不止一次需要這樣的函數,您可以編寫類似的函數自己而不是將該代碼放在 class 的多個地方的函數中。 定義一次,多次使用。
// a function to get the length of a null terminated C string
unsigned len(const char* chars) {
unsigned result = 0;
for(;*chars != '\0'; ++chars, ++result) {}
return result;
}
// A function to copy a certain amount of chars
void cpy(const char* from, char* to, unsigned len) {
for(; len; --len, ++from, ++to) {
*to = *from;
}
}
有了這些,您的構造函數將非常簡單。 我故意不在這里使用成員初始化器列表- 但請檢查它們。
String::String() { // default ctor
size = 0;
buffer = new char[size + 1]{}; // {} makes it zero initialized
// buffer[0] = '\0'; // or you could do this instead
}
String::String(const char* chars) { // converting ctor
size = len(chars); // use the len() function
buffer = new char[size + 1];
cpy(chars, buffer, size + 1); // and use the cpy() function
}
String::String(const String& s) { // copy ctor
size = s.size;
buffer = new char[size + 1];
cpy(s.buffer, buffer, size + 1); // use the cpy() function again
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.