C++ 我可以超载吗<&书信电报;操作员要使用std::string吗?

C++ 我可以超载吗<&书信电报;操作员要使用std::string吗?,c++,stl,mfc,C++,Stl,Mfc,我在MFC应用程序中使用std::string,我想将其存储在doc的Serialize()函数中。我不想将它们存储为CString,因为它在其中写入自己的内容,我的目标是创建一个我知道格式的文件,并且可以被其他应用程序读取,而不需要CString。因此,我想将std::strings存储为4字节(int)字符串长度,后跟包含该字符串的缓冲区大小 void CMyDoc::Serialize(CArchive& ar) { std::string theString;

我在MFC应用程序中使用std::string,我想将其存储在doc的Serialize()函数中。我不想将它们存储为CString,因为它在其中写入自己的内容,我的目标是创建一个我知道格式的文件,并且可以被其他应用程序读取,而不需要CString。因此,我想将std::strings存储为4字节(int)字符串长度,后跟包含该字符串的缓冲区大小

void CMyDoc::Serialize(CArchive& ar)
{
    std::string theString;

    if (ar.IsStoring())
    {
        // TODO: add storing code here
        int size = theString.size();
        ar << size;
        ar.Write( theString.c_str(), size );

    }
    else
    {
        // TODO: add loading code here
        int size = 0;
        ar >> size;
        char * bfr = new char[ size ];
        ar.Read( bfr, size);
        theString = bfr;
        delete [] bfr;
    }
}
void CMyDoc::序列化(CArchive&ar)
{
std::字符串字符串;
if(ar.IsStoring())
{
//TODO:在此处添加存储代码
int size=string.size();
ar>大小;
char*bfr=新字符[大小];
应力读数(bfr,尺寸);
字符串=bfr;
删除[]bfr;
}
}

上面的代码不是很好,我必须分配一个临时bfr来读取字符串。首先,我可以不使用临时缓冲区直接将字符串读入std::string吗?第二,我可以重载吗?如果您使用的库仅适用于c样式字符串,则没有安全的方法。这个问题在C++0x中已修复。 大概是

// NOT PORTABLE, don't do this
theString.resize(size);
ar.Read( const_cast<char *>(theString.c_str(), size);
//不可移植,不要这样做
字符串。调整大小(大小);
ar.Read(const_cast(字符串c_str(),大小);
这可能会起作用,但它可能会在以后产生一些微妙的、难以跟踪的bug。 当然,您的问题意味着您已经分析了代码,并且发现创建缓冲区和复制数据两次实际上是代码中的一个瓶颈。如果您没有这样做,那么您不应该担心效率低下。

尝试:

theString.resize(size);
ar.Read(&theString[0], size);

技术上
&字符串[0]不能保证指向一个连续的字符缓冲区,但是C++委员会做了一个调查,发现所有现有的实现都是这样工作的。

< P>我想您可能违反STL指南,继承<代码> STD::String < /Cord>,并添加自己的缓冲吸收器/ SETTER。然后重写STD::String和Trf的复制构造函数。er缓冲区的所有权。

您可以从stl字符串构建一个就地CString,并将其序列化。类似于:

CString c_string(my_stl_string.c_str();
ar << c_string;
CString c_string(my_stl_string.c_str();

ar出于各种原因,以CString形式写入数据可能更好,但是如果您必须将字符串(m_sString)转换为ASCII字符串,可能类似的方式对您适用

void myclass::Serialize(CArchive & ar)
{
    CHAR* buf;
    DWORD len;
    if (ar.IsStoring()) // Writing
    {
        len = m_sString.GetLength(); // Instead of null terminated string, store size.
        ar << len;
        buf = (CHAR*)malloc(len);
        WideCharToMultiByte(CP_UTF8, 0, m_sString, len, buf, len, NULL, NULL); // Convert wide to single bytes
        ar.Write(buf, len); // Write ascii chars
        free(buf);
    }
    else // Reading
    {
        ar >> len;
        buf = (CHAR*)malloc(len);
        ar.Read(buf, len); // Read ascii string
        MultiByteToWideChar(CP_UTF8, 0, buf, len, m_sString.GetBufferSetLength(len), len); // Convert ascii bytes to CString wide bytes
        free(buf);
    }
}
void myclass::Serialize(CArchive&ar)
{
CHAR*buf;
德沃德·伦;
if(ar.IsStoring())//写入
{
len=m_sString.GetLength();//存储大小,而不是以null结尾的字符串。
ar>len;
buf=(CHAR*)malloc(len);
ar.Read(buf,len);//读取ascii字符串
MultiByteToWideChar(CP_UTF8,0,buf,len,m_sString.GetBufferSetLength(len),len);//将ascii字节转换为CString宽字节
免费(buf);
}
}
我尝试过这个方法,但是c_str()返回一个“const char*”,这是一个问题。我可能可以将它简单地键入为“char*”,但这会有点违反c_str()函数。因此“不要这样做”注释。您可以使用
std::vector
或者因为您使用的是MFC land use
CString
CArchive& operator<<(CArchive rhs, string lhs) {
    CString c_string(lhs.c_str());
    rhs << c_string;
}
void myclass::Serialize(CArchive & ar)
{
    CHAR* buf;
    DWORD len;
    if (ar.IsStoring()) // Writing
    {
        len = m_sString.GetLength(); // Instead of null terminated string, store size.
        ar << len;
        buf = (CHAR*)malloc(len);
        WideCharToMultiByte(CP_UTF8, 0, m_sString, len, buf, len, NULL, NULL); // Convert wide to single bytes
        ar.Write(buf, len); // Write ascii chars
        free(buf);
    }
    else // Reading
    {
        ar >> len;
        buf = (CHAR*)malloc(len);
        ar.Read(buf, len); // Read ascii string
        MultiByteToWideChar(CP_UTF8, 0, buf, len, m_sString.GetBufferSetLength(len), len); // Convert ascii bytes to CString wide bytes
        free(buf);
    }
}