i'm just trying to write a simple mystring class but I keep running into one error after another.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define dontdeletenodes
#ifndef NODE_H
#define NODE_H

template <class thing>
struct node
{
    thing it;
    node * next;
    node(){it = 0; next = 0;}
    ~node(){
        #ifndef dontdeletenodes
        delete [] next;
        #endif
        }
};
#endif 

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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#ifdef STRING_H
#undef STRING_H
#endif

#ifndef MYSTRING_H
#define MYSTRING_H

#include "node.h"
#include <iostream>

static int total_mystring_allocated = 0;
static int total_mystring_active = 0;

template <class thing>
class mystring
{
    public: node<thing> next;
    public:
    static int num_of_this_allocated, num_of_this_active;
    mystring()
    { ++num_of_this_allocated; ++num_of_this_active; ++total_mystring_allocated; ++total_mystring_active;  }

    //#ifdef STRING_H
    //#define STRING
    #ifdef _GLIBCXX_STRING
    mystring(string & str)
        {
            exit(24);
        ++num_of_this_allocated; ++num_of_this_active; ++total_mystring_allocated; ++total_mystring_active;
            int s = str.size();
            for (int i = 0; i < s; ++i)
                {
                    next.it = str[i];
                    next.next = new node<thing>;
                    next.next = next->next;
                }
        }

    mystring(const string & str)
    {
        cout << "str = " << str << endl;
        ++num_of_this_allocated; ++num_of_this_active; ++total_mystring_allocated; ++total_mystring_active;
        int s = str.size();
        cout << "s = " << s << endl;
        next.next = new node <thing>;
        for (int i = 0; i < s; ++i)
            {//cout << "i = " << i << endl;
                next.it = str[i];
                next.next = new node<thing>;
                next.next->next = next.next->next;
            }
        cout << "we make it here.\n" << flush;
    }


    #endif

    mystring(const mystring<thing> & dup)
    {//exit(45);
        ++num_of_this_allocated; ++num_of_this_active; ++total_mystring_allocated; ++total_mystring_active;
        //*this = dup;
        //int s = dup.size(); //this wont compile for some very strange reason.
        int s = dup.size();

    }


    ~mystring()
    {cout << "we are destructing. \n" << endl;
        --num_of_this_active;
        --total_mystring_active;
        //delete [] next;
        //delete next;
    }

    mystring<thing> operator = (string rhs)
    {exit(47);
        int s = rhs.size();
        for (int i = 0; i < s; ++s)
            {
                char l;
                //char l = s[i];
                //l >> *this;
            }
    }


    mystring<thing> operator = (mystring<thing> rhs)
    {exit(46);
        delete [] next.next;
        int s = rhs.size();
        if (s == 0)
            return mystring<thing>();
        next.next = new node<thing>;
        next.it = rhs[0];
        next.next = next.next -> next;
        for (int i = 1; i < s; ++i)
            {
                next.it = rhs[i];
                next.next = new node<thing>;
                next.next = next.next -> next;
            }
        return *this;
    }

    bool operator == (mystring<thing> rhs)
    {
        int s = size();
        if (s != rhs.size())
            return false;
        for (int i = 0; i < s; ++i)
            {
                if (*this[i] != rhs[i])
                    return false;
            }
        return true;
    }

    thing operator [](const int & index)
    {//need to do error checking yet still.

        mystring<thing> copy(*this);
        for (int i = 0; i < index; ++i)
            {
                copy.next.next = copy.next.next->next;
            }
        return copy.next.it;
    }

    mystring<thing> operator + (const mystring<thing> & rhs)
    {
        mystring<thing> rv(*this);
        int s = rv.size();
        for (int i = 0; i < s; ++i);
            rv.next = rv.next -> next;
        s = rhs.size();
        for (int i = 0; i < s; ++i)
            {
                rv.next->next = new node<thing>;
                rv.next = rv.next->next;
                rv.next-> it = rhs[i];
            }
        return rv;
    }

    void operator += (const mystring<thing> & rhs)
    {
        *this = *this + rhs;
        return;
    }


    //#ifdef IOSTREAM
    #ifdef _GLIBCXX_IOSTREAM
    friend ostream& operator<<(ostream& out, mystring<thing>& string) // output
    {
        int s = string.size();
        cout << "here s = " << s << endl;
        for (int i = 0; i < s; ++i)
            {
                out << string[i];
                out << i;
            }
        return out;
    }
    #endif

    #ifndef _GLIBCXX_IOSTREAM
    friend ostream& operator <<(ostream& out, const mystring<thing> & string)
    {exit(300);
        //printf("
        return out;
    }
    #endif

    bool operator >> (char ch)
    {
        if (next.it = ch)
            return true;
        else return false;
    }



    int size()
    {
        int irv = 0;
        if (next.next == 0)
            return irv;
        //exit(22);//make sit here
        mystring<thing> copy(*this); //doesn't make it here
        //exit(33);
        while(copy.next.it != 0)
            {
                copy.next.next = copy.next.next->next;
                ++irv;
            }
        return irv;
    }
};


template<class thing>
int mystring<thing> :: num_of_this_allocated = 0;

template<class thing>
int mystring<thing> :: num_of_this_active = 0;

#endif


What is wrong with c++?
Last edited on
bump
http://www.cplusplus.com/doc/tutorial/namespaces/ (the last title could be helpful)

Athar wrote:
When you are going to use functions from a header, you have to include it (obviously).
It doesn't count if another header (like <iostream>) happens to include <cstdlib> by chance. That's an implementation detail and it is nothing you are allowed to rely on. It might just as well change in the next update to your standard library implementation.

That will make your program to compile.

Also:
If you allocate with new then deallocate with delete
If you allocate with new [] then deallocate with delete []
Last edited on
well aren't there any user defined classes for a string on cplusplus.com. Its a fairly straightforward topic, or so I would think... i'm surprised I haven't been able to google more of it on this site.
How do you intend to instantiate this class? (what is thing expected to be?) In the node class zero is assigned to it. Also, I think you want delete, not delete[], in there.

What is this concept of a node in a string class, anyway? This looks like a messy merge of a linked list and a string class all in one. Google for examples of string classes [again] (there are plenty of examples out there).
Last edited on
well i just threw it together in a hurry, and yeah i guess it is sorta a linked list, but whats the difference right?

And doesn't delete[] just automatically free up any and all memory that had been allocated for a specific variable?

And thing is just supposed to be anything, probably will be instantiating it 99% of the time with <char> though. But i just thought that it might be useful if someday I wanted to have a string of ints for example, i wouldn't have to bother to remember the code for getting the # of digits in an int, i could simply just call the .size() function.
Ok i revised it somewhat.

Have I fixed most of the issues yet?

Am I off to a good start?

Any suggestions?

type.h:
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
#ifndef TYPE_H
#define TYPE_H

using namespace std;

#define alphabetate( name ) # name

enum KINDS { INT = 1, BOOL, FLOAT, DOUBLE, CHAR, STRING, CHARPOINTER };
const char * kindnames[] = {"", alphabetate(INT), alphabetate(BOOL), alphabetate(FLOAT), alphabetate(DOUBLE), alphabetate(CHAR),
    alphabetate(STRING), alphabetate(CHARPOINTER)};

#include <ostream>
#include <iostream>

string printify_kinds_wrapper(KINDS KIN)
{
    return kindnames[KIN];
}


string printify_kinds(int kin)
{
    cout << "kin = " << kin << endl;
    return printify_kinds_wrapper((KINDS) kin);
}

template <class it> int get_type(const it & other) {  return -1;}
int get_type(const string & s) { return STRING;}
int get_type(const char & c) { return CHAR; }
int get_type(const double & d) {return DOUBLE; }
int get_type(const float & f) { return FLOAT; }
int get_type(const bool & b) { return BOOL; }
int get_type(const int & i) { return INT; }
int get_type(const char * & cp) { return CHARPOINTER;}
int get_type(char * cp) { return CHARPOINTER; }
#endif 


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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#ifndef MYSTRING_H
#define MYSTRING_H

#include "type.h"

using namespace std;

static int total_mystring_allocated = 0;
static int total_mystring_active = 0;

template <class thing>
class mystring
{
    bool nul;
    thing * it;
    int num_entries;
    char * caddress;
    bool resize(const int & ns);
    public:
    static int num_of_this_allocated, num_of_this_active;
    int size();
    char * c_str(char *& c);
    mystring()
        {
            it = new thing;
            it[0] = 0;
            nul = true;
            num_entries = 0;
            caddress = new char [10];
            caddress[0] = '\0';
            ++num_of_this_allocated; ++num_of_this_active; ++total_mystring_allocated; ++total_mystring_active;
            return;
        }
    mystring(const mystring & astr)
        {
            ++num_of_this_allocated; ++num_of_this_active; ++total_mystring_allocated; ++total_mystring_active;
            if (astr.size() == 0)
                {
                    mystring();
                    return;
                }
            else
                {
                    int s = astr.size();
                    it = new thing[s + 1];
                    nul = false; num_entries = s;
                    for (int i = 0; i < s; ++i)
                        {
                            it[i] = astr.it[i];
                        }
                    it[s] = 0;
                    caddress = new char [10]; caddress[0] = '\0';
                    return;
                }
        }
    mystring(const char cca[] )
        {
            thing tp; int tr = get_type(tp);
            ++num_of_this_allocated; ++num_of_this_active; ++total_mystring_allocated; ++total_mystring_active;
            int news = 0; while(cca[news++] != 0); num_entries = news;
            if ( news  > 1) it = new thing [news];
                else it = new thing; int i = 0;
            for (i = 0; i < news; ++i)
                if (tr == INT || tr == BOOL)
                    it[i] = cca[i] - 48;
                else it[i] = cca[i];
            it[i] = 0;
            caddress = new char [10]; caddress[0] = '\0';
        }

    ~mystring()
        {
            --num_of_this_active;
            --total_mystring_active;

            delete [] caddress;
            if (nul)
                return;
            else if (size() == 1)
                {
                    delete it;
                    return;
                }
            else if (size() > 1)
                {
                    delete [] it;
                    return;
                }
            return;
        }

    //thing operator [](const int & index)
    char operator [](const int & index)
    {//need to do error checking yet still.
        char c = 0; thing tp; int tr = get_type(tp), i = 0;
        if (tr == INT || tr == BOOL)
            c = it[index] + 48;
        else c = it[index];
        return c;
    }



    #ifdef _GLIBCXX_IOSTREAM
    friend ostream& operator<<(ostream& out, mystring<thing>& string) // output
    {
        int s = string.size();
        //cout << "here s = " << s << endl;
        for (int i = 0; i < s; ++i)
            {
                out << string[i];
            }
        return out;
    }
    #endif

    mystring<thing> operator + (const mystring<thing> & rhs)
        {
            thing tp; int tr = get_type(tp);
            mystring<thing> rv(*this);
            if (tr == INT)
                {
                }
            if (tr == CHAR)
                {
                    rv.it += rhs.c_str();
                }

            return rv;
        }

};

template <class thing>
inline int mystring<thing>::size()
{
    return num_entries;
}

template <class thing>
inline char * mystring<thing>:: c_str(char *& c)
{
    delete [] caddress;
    if (size() == 0)
        {
            caddress = new char [10];
            caddress[0] = '\0';
            return caddress;
        }
    if (size() == 1)
        {
            caddress = new char [10];
            caddress[0] = it[0];
            caddress[1] = '\0';
            return caddress;
        }
    if (size() > 1)
        {
            int s = size();
            caddress = new char[s];
            thing tp;
            int tr = get_type(tp);
            if (tr == INT || tr == BOOL)
                for (int i = 0; i < s; ++i)
                    caddress[i] = it[i] + 48;
            else for (int i = 0; i < s; ++i)
                caddress[i] = it[i];
            caddress[s] = 0;
            return caddress;
        }
}

template <class thing>
inline bool mystring<thing>::resize(const int & ns)
{
    if (ns < 0)
        return false;
    if (ns == 0)
        {
            if (nul)
                return false;
            else
                {
                    if (size() > 1)
                        {
                            delete [] it;
                            nul = true;
                        }
                    else delete it;
                    return true;
                }
        }
    if (ns < size())
        {//keeping allocated memory for now
            it[ns] = 0;
            num_entries = ns;
            return true;
        }
    else if (ns == size())
        return false;
    else if (ns > size())
        {
            if (nul)
                {
                    if (ns == 1)
                        {
                            it = new thing;
                            nul = false;
                            it[1] = 0;
                        }
                    if (ns > 1)
                        {
                            it = new thing[ns];
                            nul = false;
                            it[ns] = 0;
                        }
                }
            mystring copy(*this);
            if (size() == 1)
                delete it;
            else delete [] it;
            it = new thing[ns];
            int i = 0;
            for (i; i < copy.size(); ++i)
                it[i] = copy[i];
            while(i++ < ns)
                it[i] = 0;
            num_entries = ns;
            nul = false;
        }

}

template<class thing>
int mystring<thing> :: num_of_this_allocated = 0;

template<class thing>
int mystring<thing> :: num_of_this_active = 0;

#endif 
Include all that you need. (string)
Don't use namespace in headers. It pollutes whatever it's next.
AFAIK template and inline functions definitions must be in headers. Others mustn't (linker multiple definition)

Check out for memory leaks.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mystring<something_big>();

    mystring()
        {
            it = new thing;
            it[0] = 0; //quite restrictive
            nul = true;
//...
    ~mystring()
        {
            --num_of_this_active;
            --total_mystring_active;

            delete [] caddress;
            if (nul)
                return; //'it' was not released 
¿why are you mixing new and new[]?

char * mystring<thing>:: c_str(char *& c) //c is not used in the method
1
2
3
    if (size() == 0)//...
    if (size() == 1)//...
    if (size() > 1)//... 
That is ugly


¿What are those magic numbers?

Don't be afraid of white space and comments.
That is ugly

I used a char *& param so I could return the address of a non-local variable. which I think is needed.

Those magic numbers indicate if I need to call delete [] or just delete.
All the ifs all over the place. That is ugly. ¿why don't just new[1]; so you can always delete[]? ¿why don't just use std::vector ?

You don't use that parameter...

These magic numbers:
1
2
caddress = new char [10];
caddress[i] = it[i] + 48;
hmmm not sure, think I planned on using caddress when calling c.str(), which I guess I would have to make it public then....

and 10 is meaningless but +48 is for ints. I wanted one single class that I could use for strings and ints and call the same function size() to get meaningful results. .size() for a char * returns the number of characters, .size() for an int returns the number of digits.

Plus it really sucks when writing a templated function only to find it don't work for some classes because some classes might not have a certain function with the same name such as size() or c_str() or etc you get the idea.
Topic archived. No new replies allowed.