我想编写一个类似于串的加法操作的程序,在编译时没有问题,可在运行时没能得到想要的结果,不知道为什么,请大虾们帮忙看一看吧:
头文件:
class character_string
{
public:
character_string()
{
p = NULL;
}
character_string(char *);
friend character_string operator + (character_string &, character_string &);
void display();private:
char *p;
};.cpp文件:character_string::character_string(char *str)
{
p = str;
}character_string operator + (character_string &str1,character_string &str2)
{
char *p;
char ch[100] = {};
p = ch; while ( *str1.p != '\0')
{
*p = *str1.p;
str1.p++;
p++;
} while( *str2.p != '\0')
{
*p = *str2.p;
str2.p++;
p++;
} p = ch; character_string new_string(p);
return new_string;
}int main()
 {
char *p1 = "I'm a girl.";
char *p2 = "And my boyfriend is a boy.";
character_string str1(p1);
character_string str2(p2); character_string new_str;
new_str = str1 + str2;
new_str.display();}
让我感到疑惑的是,在调试状态下的监视窗口里,主程序中的在最后一行执行前new_str里的指针里的内容还是正确的,可到new_str.display()这一行程序时,成员函数里的指针p的内容就变成了一连串的”烫“了,并且我看指针的地址还是new_str里p的地址。为什么会出现这样的错误呢?我真搞不明白……

解决方案 »

  1.   

    character_string::character_string(char *str) 

      if(p!=NULL)
        delete[] p;
      int len = strlen(str);
      p = new char[len+1];
      strcpy(p,str);
    }
    character_string::~character_string()
    {
      if(p!=NULL)
        delete[] p;
      

  2.   

    我的.display()程序是这样写的:
    void character_string::display()
    {
    cout << p << endl;
    }
      

  3.   


    调试状态下的黄色指针指向的那一行并没有执行,也就是说你的指针指到new_str.display()这一行时,上一行执行完,new_str.display()还没有执行。你的new_str.p最终指向的是operator +中的局部变量ch,因此会有问题。
      

  4.   

    原来是因为指针指向了局部变量……那如果按照我程序里的思路应该怎么改呢?我试着将ch 在头文件里定义成全局变量,连接时提示变量重复;在主程序里定义ch为全局变量,连接时提示在"+"程序中ch没有定义。这是为什么呢?
      

  5.   


    new_str = str1 + str2; //用临时对象来进行赋值运算,而你的赋值操作没有重载,会按默认的赋值运算进行赋值(即指针赋值,而后临时对象的成员从堆栈上结束生命周期,自然会出错)。
      

  6.   

    用指向临时变量的指针来进行赋值确实是造成这个程序出错的原因,可为什么调试时当黄色的箭头指向new_str.display(),也就是执行完"new_str = str1 + str2;"这一句时,监视窗口里的new_str里的内容是两个字串相加的内容。一直到执行完new_str.display()时,new_str里的内容才变为"烫“。是不是有的时候监视窗口里的数据也会出错,有时也值得怀疑呢?
      

  7.   

    根据我1楼的描述修改你的构造函数,并添加析构函数释放内存,不要直接赋值指针,通过strcpy拷贝字符串。
      

  8.   

    局部变量的问题
    在构造函数中分配内存,并将传进来的值保存下来,内存在析构函数中释放给CString的构造函数和析构函数你看看CString::CString(TCHAR ch, int nLength)
    {
    Init();
    if (nLength >= 1)
    {
    AllocBuffer(nLength);
    #ifdef _UNICODE
    for (int i = 0; i < nLength; i++)
    m_pchData[i] = ch;
    #else
    memset(m_pchData, ch, nLength);
    #endif
    }
    }CString::CString(LPCTSTR lpch, int nLength)
    {
    Init();
    if (nLength != 0)
    {
    ASSERT(AfxIsValidAddress(lpch, nLength, FALSE));
    AllocBuffer(nLength);
    memcpy(m_pchData, lpch, nLength*sizeof(TCHAR));
    }
    }/////////////////////////////////////////////////////////////////////////////
    // Special conversion constructors#ifdef _UNICODE
    CString::CString(LPCSTR lpsz, int nLength)
    {
    Init();
    if (nLength != 0)
    {
    AllocBuffer(nLength);
    int n = ::MultiByteToWideChar(CP_ACP, 0, lpsz, nLength, m_pchData, nLength+1);
    ReleaseBuffer(n >= 0 ? n : -1);
    }
    }
    #else //_UNICODE
    CString::CString(LPCWSTR lpsz, int nLength)
    {
    Init();
    if (nLength != 0)
    {
    AllocBuffer(nLength*2);
    int n = ::WideCharToMultiByte(CP_ACP, 0, lpsz, nLength, m_pchData,
    (nLength*2)+1, NULL, NULL);
    ReleaseBuffer(n >= 0 ? n : -1);
    }
    }
    #endif //!_UNICODE//////////////////////////////////////////////////////////////////////////////
    // Assignment operatorsconst CString& CString::operator=(TCHAR ch)
    {
    AssignCopy(1, &ch);
    return *this;
    }//////////////////////////////////////////////////////////////////////////////
    // less common string expressionsCString AFXAPI operator+(const CString& string1, TCHAR ch)
    {
    CString s;
    s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, 1, &ch);
    return s;
    }CString AFXAPI operator+(TCHAR ch, const CString& string)
    {
    CString s;
    s.ConcatCopy(1, &ch, string.GetData()->nDataLength, string.m_pchData);
    return s;
    }
      

  9.   

    按照您1楼的带参构造函数的写法,我修改了程序,但差不多的情况还是发生了。我把修改后的代码贴出来,还请大虾看一看呀!
    .h:
    class character_string
    {
    public:
    character_string()
    {
    p = NULL;
    }
    character_string(char *);
    ~character_string();
    friend char* operator + (character_string &, character_string &);
    bool operator > (character_string &);
    bool operator < (character_string &);
    bool operator == (character_string &);
    void display();private:
    char *p;
    };.cpp:character_string::character_string(char *str)
    {
    //  这里是不是应该杠掉?要不然连character_string str1(p1);这一句都无法实现……
    //  if(p != NULL)
    //  {
    //  delete[] p;
    //  }
    int len;
    len = strlen(str);
    p = new char[len + 1];
    strcpy(p, str);}character_string::~character_string()
    {
    if(p != NULL)
    {
    delete[] p;
    }
    }char* operator + (character_string &str1,character_string &str2)
    {
    char *p;
    char ch[100] = {};
    p = ch; char *p1 = str1.p;
    char *p2 = str2.p; while ( *p1 != '\0')
    {
    *p = *p1;
    p1++;
    p++;
    } while( *p2 != '\0')
    {
    *p = *p2;
    p2++;
    p++;
    }  p = ch;
    return p;
    }
    int main()
     {
    char *p1 = "I'm a girl.";
    char *p2 = "And my boyfriend is a boy.";
    character_string str1(p1);
    character_string str2(p2); char *s;
    s = str1 + str2; //到这里时,s中的内容还是正确的
    character_string new_str(s);  //进入到这个构造函数里时,刚进入时s的内容正确;可当执行完一句,即int len;时,s的值又变成了“烫”!这是为什么呢?难以理解……难道我的编译器有问题?我用的是vs2008……
    new_str.display();
    cout << endl << endl; str1.display();
    compare_string(str1, str2);
    str2.display();
    cout << endl; return 0;
    }
      

  10.   

    character_string::character_string(char *str) 

    int len; 
    len = strlen(str); 
    p = new char[len + 1]; 
    strcpy(p, str); 
    }character_string& operator + (character_string &str1,character_string &str2) 

    char *pp; 
    char ch[100] = {}; 
    pp = ch; char *p1 = str1.p; 
    char *p2 = str2.p; while ( *p1 != '\0') 

    *pp++ = *p1++; 
    } while( *p2 != '\0') 

    *pp++ = *p2++; 
    } pp = ch; 
    return character_string(pp);

      

  11.   

    这样试过了,也还是不行啊?是不是我主程序调用时有问题呢?
    character_string& operator + (character_string &str1,character_string &str2)
    返回值为character_string&的引用,这在主程序里怎么调用呢?
    如果返回值类型设为character_string,在主程序的new_str = str1 + str2;这一句还是会出错……而且程序会出现"Debug Assersion Failed"这样严重的错误……
      

  12.   

    能解释一下:“return character_string(pp);”这一句吗?它调用了一个含参的构造函数,但返回的是什么呢?为什么直接返回
    character_string(pp)就可以,而写成:“character_string new_str(pp); return new_str;"就不行呢?还是也可以呢?我
    刚开始学c++,有些不清楚,希望能得到各位大虾的帮助,呵呵~谢谢!
      

  13.   

    调试了一下,下面是完整的代码class character_string 

    public: 
    character_string() 

    p = NULL; 

    character_string(char *); 
    ~character_string(); 
    //character_string(const character_string& src);
    friend character_string operator + (character_string &, character_string &); 
    //bool operator > (character_string &); 
    //bool operator < (character_string &); 
    //bool operator == (character_string &); 
    void display(); private: 
    char *p; 
    };character_string::character_string(char *str) 

    int len = strlen(str); 
    p = new char[len + 1]; 
    strcpy(p, str); 
    } character_string::~character_string() 

    if(p != NULL) 

    delete[] p; 

    } character_string& operator + (character_string &str1,character_string &str2) 

    char *pp; 
    char ch[100] = {}; 
    pp = ch;  char *p1 = str1.p; 
    char *p2 = str2.p;  while ( *p1 != '\0') 

    *pp++ = *p1++; 
    }  while( *p2 != '\0') 

    *pp++ = *p2++; 
    }  pp = ch; 
    return character_string(pp); 
    }// character_string::character_string(const character_string& src)
    // {
    //  int len = strlen(src.p);
    //  p = new char[len+1];
    //  strcpy(p,src.p);
    // }void character_string::display()
    {
    cout<<this->p<<endl;
    }int main() 

    char *p1 = "I'm a girl."; 
    char *p2 = "And my boyfriend is a boy."; 
    character_string str1(p1); 
    character_string str2(p2);  character_string s = str1 + str2; 
    s.display();
    cout << endl << endl;  getchar();
    return 0; 
    }