字符串类中运算符重载出现的一个问题

  上机辅导。学生的一个程序莫名出问题。她是在做一个String类,主要是要实现字符串的连接。

  程序是这样的,请读者将其拷到IDE,边看边调:

#include <iostream>
#include <cassert>
#include <cstring>
using namespace std;
class String
{
private:
    char* p;
    int len;
public:
    String();
    String(const char* s);
    String(const String& s);
    ~String();//问题出现在这儿
    void show();
    friend String operator+(const String& s1,const String& s2);
    friend String operator-(const String& s1,const String& s2);
};
String::String()
{
    len=0;
    p=NULL;
}
String::String(const char* s)
{
    len=strlen(s);
    p=new char[len+1];
    strcpy(p,s);
}
String::String(const String& s)
{
    len=s.len;
    if(p!=NULL)delete []p;
    p=new char[len+1];
    strcpy(p,s.p);
}
String operator+(const String& s1,const String& s2)
{
    String total;
    total.len=s1.len+s2.len;
    total.p=new char[total.len+1];
    strcpy(total.p,s1.p);
    strcat(total.p,s2.p);
    return total;
}
String operator-(const String& s1,const String& s2)
{
    char* c1=new char[s1.len+1];
    strcpy(c1,s1.p);
    int i=s1.len-1;
    while(s1.p[i]!=‘ ‘&&i>=0)--i;
    c1[i+1]=‘\0‘;
    char* c2=new char[s2.len+1];
    strcpy(c2,s2.p);
    i=0;
    while(i<s2.len&&c2[i]==‘ ‘)++i;
    int j=0;
    while(c2[i]!=‘\0‘&&i<s2.len)
    {
        c2[j]=c2[i];
        ++i;
        ++j;
    }
    c2[j]=‘\0‘;
    String s;
    s.len=s1.len+s2.len;
    s.p=new char[s.len];
    strcpy(s.p,c1);
    strcat(s.p,c2);
    delete c1;
    delete c2;
    return s;
}
void String::show()
{
    cout<<p<<endl;
}
String::~String()
{
    delete []p;
}

int main()
{
    String str1("123"),str2("456"),str3;
    str3=str1+str2;
    str3.show();
    str3=str1-str2;
    str3.show();
    return 0;
}

  问题的表现是,str3.show();的输出是几个莫名的符号!

  我让她单步跟踪一下,却发现无论断点设在哪里,总是要进到析构函数~String()中去!

  恰其他同学的问题不少,我让她将这个程序给我发邮件,她不要在此纠缠。我清楚,这里有指针成员。祸水应该与此相关。

  学习越来越深入,学生出问题的程序,常需要仔细阅读后才能给指导意见了。

  午睡后,打开邮件。将程序拷入IDE,已经注意到了执行str3=str1+str2;时,需要有的赋值运算符=的重载。试图找一下单步时进入~String()时的场景,却未遂。

  在我的IDE下,str3=str1+str2;的结果正常,str3=str1-str2;的结果却异常。野指针的表征,真伪混杂最头疼。

  重载赋值运算=,在类声明中加:

    String &operator=(const String& s1);

  实现为:

String &String::operator=(const String &s1)
{
    if(!this->p)
        delete []p;
    p=new char(s1.len+1);
    strcpy(p,s1.p);
    len=s1.len;
    return *this;
}

  先向学生交作业。进入~String()的问题是否还在?暂时放下,待回音。

时间: 2024-10-12 23:52:38

字符串类中运算符重载出现的一个问题的相关文章

[c++]String字符串类的运算符重载

在c++中有一个新定义的类型string,可以不用那么麻烦的操作字符串,并且一些高级的运算符重载让她的使用更加便捷 下面是String类的定义和成员函数的定义: #ifndef operator_operator_h #define operator_operator_h #include<iostream> #include<string.h> using namespace std; class String { friend ostream& operator<

YTUOJ-矩形类中运算符重载

Description 定义一个矩形类,数据成员包括左下角和右上角坐标,定义的成员函数包括必要的构造函数.输入坐标的函数,实现矩形加法,以及计算并输出矩形面积的函数.要求使用提示中给出的测试函数并不得改动. 两个矩形相加的规则是:决定矩形的对应坐标分别相加,如 左下角(1,2),右上角(3,4)的矩形,与 左下角(2,3),右上角(4,5)的矩形相加,得到的矩形是 左下角(3,5),右上角(7,9)的矩形. 这个规则没有几何意义,就这么定义好了. 输出面积的功能通过重载"<<&quo

第十五周oj刷题—— Problem C: 矩形类中运算符重载【C++】

Description 定义一个矩形类,数据成员包括左下角和右上角坐标,定义的成员函数包括必要的构造函数.输入坐标的函数,实现矩形加法,以及计算并输出矩形面积的函数.要求使用提示中给出的测试函数并不得改动. 两个矩形相加的规则是:决定矩形的对应坐标分别相加,如 左下角(1,2),右上角(3,4)的矩形,与 左下角(2,3),右上角(4,5)的矩形相加,得到的矩形是 左下角(3,5),右上角(7,9)的矩形. 这个规则没有几何意义,就这么定义好了. 输出面积的功能通过重载"<<&quo

C#中运算符重载

很多语言都允许程序员使用运算符重载,尽管从编程的角度看,这没有其必要性,但是对于代码来讲可以提高它的可读性,带来许多方便之处.最简单的例子就是,我们用String类的时候,用"+"运算符直接实现字符串的连接,很方便很直观. 运算符重载实例: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Xml.Linq; namespace impli

sdut 4-1 复数类的运算符重载

4-1 复数类的运算符重载 Time Limit: 1000MS Memory limit: 65536K 题目描述 通过本题目的练习可以掌握成员运算符重载及友元运算符重载 要求定义一个复数类,重载加法和减法运算符以适应对复数运算的要求,重载插入运算符(<<)以方便输出一个复数的要求. 输入 要求在主函数中创建对象时初始化对象的值. 输出 输出数据共有4行,分别代表a,b的值和它们求和.求差后的值 示例输入 无 示例输出 a=3.2+4.5i b=8.9+5.6i a+b=12.1+10.1i

4-1复数类的运算符重载(SDUTOJ2677)

http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2677&cid=1275 题目描述 通过本题目的练习可以掌握成员运算符重载及友元运算符重载 要求定义一个复数类,重载加法和减法运算符以适应对复数运算的要求,重载插入运算符(<<)以方便输出一个复数的要求. 输入 要求在主函数中创建对象时初始化对象的值. 输出 输出数据共有4行,分别代表a,b的值和它们求和.求差后的值 示例输入 无 示例输出 a=3.2+4.5i b=8.9+5.6i

第十七周oj刷题——Problem O: B C++时间类的运算符重载

Description C++时间类的运算符重载 定义一个时间类Time,其数据成员为表示时间的小时(hour).分(minute),秒(second). 重载运算符"+",使之能用于时间对象的加法运算:重载运算符"<<",使之能用于时间对象的输出操作. (1)参加运算的两个操作数可以都是时间类对象,也可以其中有一个是整数(表示秒),顺序任意. 例如,t1+t2,i+t1,t1+i均合法(设i为整数表示秒数, t1,t2为时间类Time对象). (2)输

模板类与运算符重载

我自定义了一个模板类并重载了运算符,预定义实现功能为能实现对数组一般操作,类似于vector. #ifndef ARRAY_H #define ARRAY_H #include <iostream> using namespace std; template<class T> class Array{ friend ostream& operator<<(ostream&, const Array &); friend istream&

优先队列中运算符重载

1 struct node{ 2 int a; 3 int cost; 4 node(int a, int cost):a(a), cost(cost){} 5 friend bool operator < (node n1, node n2){ 6 return n1.cost > n2.cost; 7 } 8 }; 9 priority_queue<node> q; 原文地址:https://www.cnblogs.com/rstz/p/12359948.html