我主要担心的是,如果我安全,有效地执行此操作,并且大部分时间都是正确的。
我需要一些帮助来编写我的字符串类的实现。也许有人可以帮我解决一下我想知道的事情?
我正在尝试编写自己的字符串类,以实现扩展功能和学习目的。我不会用它作为std :: string的替代品,因为这可能有潜在危险。 :-P
当我使用std :: cout打印出我的字符串的内容时,我得到了一些意想不到的输出,我想我知道为什么,但我不确定。我把它缩小到我的赋值函数,因为我在字符串中存储字符的任何其他方式都可以正常工作。这是我的赋值函数:
void String::assign(const String &s)
{
unsigned bytes = s.length() + 1;
// if there is enough unused space for this assignment
if (res_ >= bytes)
{
strncpy(data_, s.c_str(), s.length()); // use that space
res_ -= bytes;
}
else
{
// allocate enough space for this assignment
data_ = new char[bytes];
strcpy(data_, s.c_str()); // copy over
}
len_ = s.length(); // optimize the length
}
我有一个构造函数,它为char ptr保留固定数量的字节以进行分配和保持。它被声明如下:
explicit String(unsigned /*rbytes*/);
res_变量只记录传入的字节数并存储它。这是string.cpp中的构造函数代码:
String::String(unsigned rbytes)
{
data_ = new char[rbytes];
len_ = 0;
res_ = rbytes;
}
我认为使用此方法会更有效,而不是为字符串分配新空间。所以当我宣布一个新的字符串时,我可以使用我最初保留的任何间距。这是我如何测试它是否有效:
#include <iostream>
#include "./string.hpp"
int main(int argc, char **argv)
{
winks::String s2(winks::String::to_string("hello"));
winks::String s(10);
std::cout << s2.c_str() << "\n" << std::endl;
std::cout << s.unused() << std::endl;
std::cout << s.c_str() << std::endl;
std::cout << s.length() << std::endl;
s.assign(winks::String::to_string("hello")); // Assign s to "hello".
std::cout << s.unused() << std::endl;
std::cout << s.c_str() << std::endl;
std::cout << s.length() << std::endl;
std::cout.flush();
std::cin.ignore();
return 0;
}
如果您关注winks :: String :: to_string,我只是将char ptr转换为我的字符串对象,如下所示:
String String::to_string(const char *c_s)
{
String temp = c_s;
return temp;
}
但是,我在这个方法中使用的构造函数是私有的,所以我强迫自己使用to_string。到目前为止,我没有遇到任何问题。我这样做的原因是为了避免重写不同参数的方法,即:char *和String
私有构造函数的代码:
String::String(const char *c_s)
{
unsigned t_len = strlen(c_s);
data_ = new char[t_len + 1];
len_ = t_len;
res_ = 0;
strcpy(data_, c_s);
}
非常感谢所有帮助。如果我没有提供有效数量的信息,请通知我你想知道的内容,我很乐意编辑我的帖子。
编辑:我没有发布完整的string.hpp和string.cpp的原因是因为它相当大,我不确定你们是否愿意。
答案 0 :(得分:2)
您必须决定是否始终将字符串内部以0结尾存储。如果不将字符串存储为终止零字节,则c_str
函数必须添加一个。否则,它不会返回C字符串。
您的assign
函数不会终止。所以要么它坏了,要么你不打算终止。如果是前者,请修复它。如果是后者,请检查c_str
函数以确保它在结尾处放置0。