problem with operator+() overloaded function

Hello guys. I did this before with built in types, but this time around I keep failing trying to do it with class objects. I was asked to write a string class which involves overloading the operator+() function so as to add one strings object to another. But after setting everything up, every time I run the programme, it crashes, without displaying anything. But without the operator+() function everything seems to go well. But again if there is any subtle problem with the rest of my code please do point me out.
Please help.
Here is the code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
  //Class declaration in header.h
#ifndef HEADER_H
#defined HEADER_H
class Strings
{
private:
    char * str;
    int len;
    static int numb_count;
public:
    //class methos
    Strings();
    Strings(const char * s);
    Strings (const Strings & s);
    //overloaded methods
    Strings  &operator=(const Strings & s);
    Strings  & operator=(const char * s);
    ~Strings() {delete [] str;}
    friend bool operator>(const Strings & s, const Strings &c);
    friend bool operator<(const Strings & s, const Strings &c);
    friend bool operator==(const Strings & s, const Strings & c);
    friend std::ostream &operator<<(std::ostream & os, Strings & s);
    friend std::istream & operator>>(std::istream & is, Strings & s);
    friend Strings operator+(const Strings & s, const Strings & b);
    void stringup();
    void stringlow();
    int charnum(char s);
    const char operator[] (int i);
    const char operator[] (int i) const;
    static int How_to();
    int length() const {return len;}

endif // HEADER_H

// the class implementation in another file
int Strings::numb_count = 0;

int Strings::How_to()
{
    return numb_count;
}

Strings::Strings(const char * s) // copy a const string to an object
{
    len = strlen(s);
    str = new char[len + 1];
    strcpy(str, s);
    numb_count++;
}

Strings::Strings() // default constructor
{
    len = 0;
    str = new char[1];
    str[0] = '\0';
    numb_count++;
}

Strings::Strings(const Strings & s) // explicit copy constructor
{
    len = s.len;
    str = new char[len + 1];
    strcpy(str, s.str);
    numb_count++;
}

Strings  &Strings::operator=(const Strings & s) //assign or initialize an object to another
{
    if (this == &s)
        return *this;
    delete [] str;
    len = s.len;
    str = new char[len + 1];
    strcpy(str, s.str);
    return *this;
}

Strings &Strings::operator=(const char * s) // assign or initialize const string to a class object
{
    delete [] str;
    len = strlen(s);
    str = new char[len + 1];
    strcpy(str, s);
    return *this;
}

bool operator>(const Strings & c, const Strings & b)
//compare string objects
{
    return (strcmp(c.str, b.str) > 0);
}

bool operator<(const Strings & c, const Strings & b)//compare string objects
{
    return (strcmp(c.str, b.str) < 0);
}

bool operator==(const Strings & c, const Strings & b) // compare string objects
{
    return (strcmp(c.str, b.str) == 0);
}


const char Strings::operator[](int i)
{
    return str[i];
}

const char Strings::operator[](int i) const // return a char element of an abject
{
    return str[i];
}

std::ostream &operator<<(std::ostream &os, Strings & c) // display a string object
{
    cout << c.str << endl;
    return os;
}

std::istream & operator>>(std::istream & is, Strings & c) // store a string to in an object
{
    char temp[80];
    is.get(temp, 80);
    if (is)
        c = temp;
    while (is && is.get() != '\n')
        continue;
    return is;
}

void Strings::stringup() // convert string to uppercase character
{
    int i;
    for (i = 0; str[i] != '\0'; i++)
    {
        str[i] = toupper(str[i]);

    }

}

void Strings::stringlow() // convert strings to lowercase characters
{
    for (int i = 0; str[i] != '\0'; i++)
        str[i] = tolower(str[i]);
}

int Strings::charnum(char s) // count how many time a char character appeared in a strings object.
{
    int numb = 0;

    for (int i = 0; str[i] != '\0'; i++)
    {
        if (str[i] == s)
            numb++;
    }

    return numb;
}
// this is the overloaded function that seems to go wrong somewhere
Strings operator+(const Strings & s, const Strings & b)
{
    Strings temp;
    temp = strcat(s.str, b.str);

temp.str = strcat(s.str, b.str);

    return temp;

I used each of the above codes by commenting out the other, but the problem still persist.
}


After adding the very last operator+() and try this here:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{

Strings kols = misbahu + ussy;

or this

Strings terminal;

terminal = ussy + misbahu;

cout << kols << endl;

cout << terminal << endl;

return 0;
}
 

Thanks.

Any help will highly be appreciated.
Last edited on
What is the length of the s.str array?
s.str is a dynamic allocation space. Its length was computed by the strlen() function by taking as an argument the const char * passed to explicit or assignment operator functions implemented above.
Here:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Strings Strings::Strings(const char * s)
{
delete [] str;

str = new char[strlen(s) + 1];

strcpy(str, s);
}

or

Strings Strings::Strings(const Strings & s)
{
delete [] str;

str = new char[strlen(s.str) + 1];

strcpy(str, s.str);

}


But I am new to c++, I don't actually know if there is any subtle problem with this.

Thanks for your response
Last edited on
Most of your code is very good.

When adding two Strings together, what is the length of the final string? You need to create a string with enough space to hold this final result, then copy the two source strings into it.

A few other comments:
- You can remove operator[](int) since operator[](int) const can be called in its place.
- It looks like numbCount is the number of strings, but I never see it getting decremented.
- You can simplify the constructors. The key is realizing that it's safe to delete a null pointer:
// Passing a default arg means this can act as default constructor too
1
2
3
4
5
6
7
8
9
10
11
12
13
Strings::Strings(const char * s = "") // copy a const string to an object
{
    str = nullptr;
    *this = s;
    numb_count++;
}

Strings::Strings(const Strings & s) // explicit copy constructor
{
    str = nullptr;
    *this = s;
    numb_count++;
}

operator<< should write to the parameter os, not cout.
Your operator+(...) is completely wrong. This is how it works:
1
2
3
4
5
6
7
8
9
10
11
Strings operator+(const Strings & s, const Strings & b)
{
    Strings temp;

temp.len = s.len + b.len;
temp.str = new char[temp.len + 1];
strcpy(temp.str s.str);
strcat(temp.str, b.str);

    return temp;
}
I now get it coder777. I now understand that was what peter87 and dhayden were trying to point out. I thought the explicit copy constructor and the assignment operator= will take care of that part for me, not realizing they only take care of the strings within them. Since operator+ is a different operator and function, it must provide a space for the object it will be creating.

Thanks guys. This is very helpful. I would've never found out this mess I did.

Thanks once again.

By the way, dhayden operator[] was meant for nonconst strings objects while operator[] const was meant for const strings object. But I may not know whether operator [] const can work with const and non const objects.

And yes you are right about the numbcount. But can I decrement it in the destructor()?
But I may not know whether operator [] const can work with const and non const objects.

It can. You can call a const member on a non-const object, but not the other way around.
And yes you are right about the numbcount. But can I decrement it in the destructor()?

Yes you can.
Thanks dhayden, peter87, and coder777. Highly appreciated
Topic archived. No new replies allowed.