这是该类的第一个实现,它只是起到作用,但还没有提供任何有用的功能:
#include <cstdlib>
#include <cstring>
class CString
{
protected:
struct CStringInfo
{
size_t Length;
size_t MaxLength;
};
public:
CString()
{
Buffer = NULL;
Assign(NULL);
}
CString(const char* chv)
{
Buffer = NULL;
Assign(chv, 0);
}
~CString()
{
if(Buffer) delete[] Buffer;
Buffer = NULL;
}
size_t GetLength()
{
if(!Buffer) Alloc(1);
return GetInfo()->Length;
}
size_t Resize(size_t size)
{
Alloc(size + 1); // + 0x00
Buffer[size] = 0;
return size;
}
bool Assign(const char* value, size_t size = 0)
{
size_t strl = ((size) ? size : strlen(value));
if(!value || !(strl = strlen(value)))
{
if(!Buffer) Alloc(1);
return false;
}
Alloc(strl + 1);
memcpy(Buffer, value, strl);
Buffer[strl] = 0;
return true;
}
CString& operator = (const char* what)
{
Assign(what);
return (*this);
}
CString& operator = (CString& string)
{
Assign(string.Buffer);
return (*this);
}
operator const char* ()
{
return Buffer;
}
protected:
char* Buffer;
void Alloc(size_t size)
{
if(!size) size = 1;
char* nb = new char[size + sizeof(CStringInfo)];
char* nbb = nb + sizeof(CStringInfo);
size_t cl = size - 1;
if(Buffer)
{
if(cl > GetInfo()->Length) cl = GetInfo()->Length;
if(cl) memcpy(nbb, Buffer, cl - 1);
nbb[cl] = 0;
*(CStringInfo*)(nb) = *(CStringInfo*)(Buffer);
delete[] (Buffer - sizeof(CStringInfo));
}
Buffer = nb;
GetInfo()->MaxLength = size;
GetInfo()->Length = cl;
}
void Free()
{
if(Buffer)
{
delete[] (Buffer - sizeof(CStringInfo));
}
}
CStringInfo* GetInfo()
{
return (CStringInfo*)(this->Buffer - sizeof(CStringInfo));
}
};
我测试的代码:
#include <cstdio>
#include "CString.hpp"
CString global_str = "global string!";
int main(int argc, char* argv[])
{
CString str = "string";
printf("Test: %s, %s\n", str, global_str);
return 0;
}
如果我在类中没有析构函数,那么我可以将它传递给printf,它会像C字符串一样正常工作。但是当我添加了析构函数时,GCC会产生以下错误:
error: cannot pass objects of non-trivially-copyable type 'class CString' through '...'
此外,早期版本的GCC会发出警告 + ud2操作码。
那么问题来了:我是否可以在GCC中使以下结构正常工作,或者是否有任何方法(可能不涉及C varargs),可以使使用方式与上述代码完全相同?
const char* operator
成为常量:const char* operator() const
——这可能甚至完全解决了问题,但我不确定。请尝试一下。如果添加一个析构函数,那么这个类就不再是POD(如果没有),这意味着它是非平凡可复制的。 - leemesCString str1; CString str2 = "text"; str1.Format("%s", str2.GetBuffer());
一个类使用第三方转换将自身格式化为自身。多好啊。我不明白的是,为什么他们没有添加像operator...()这样的东西来控制当您通过vararg传递类时实际使用的内容。 - ZZYZX