C++ Without Fear Exercise 14.3.1

Hi there. I am trying to make this code for a custom string class in the exercise:

Exercise 14.3.1. Rewrite the operator+ function as a global friend function, as just suggested. Review Chapter 13 if you need to do so. (Hint: No real change has to be made to the code other than the way the function is declared. You can still get away with having just one operator+ function.)

My original code supported this:

String b = a + "Kong"

but now I have to change it so it can also support:

String b = "Kong" + a

I tried this:

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
#include <iostream>
#include "stdafx.h"
#include <string.h>

using namespace std;

    class String {
    private:
        char *ptr;
        
    public:
        String();
        String(char *s);
        String(const String &src);
		~String();
        
        String& operator=(const String &src)
                {cpy(src.ptr); return *this; }
        String& operator=(char *s)
                {cpy(s); return *this; }
                
         String operator+(char *s);
		friend String operator+(char *s, String *ptr);
        int operator==(const String &other);
        operator char*() {return ptr; }
        
        void cat(char *s);
        void cpy(char *s);
        
    };
    
                

int _tmain() {
    String a, b, c;
    a = "I ";
    b = "am ";
    c = "so yeah. ";
    String d = "very happy!" + a + b + "very happy!" + c + "\n";
    cout << d;
    system("PAUSE");
    return 0;
}

//------------------------------------------------------
// STRING CLASS FUNCTIONS

    String::String() {
        ptr = new char[1];
        ptr[0] = '\0';
        }
    
    String::String(char *s) {
        int n = strlen(s);
        ptr = new char[n + 1];
        strcpy(ptr, s);
        }
        
    String::String(const String &src) {
        int n = strlen(src.ptr);
        ptr = new char[n + 1];
        strcpy(ptr, src.ptr);
        }
    
    String::~String() {
        delete [] ptr;
        }
    
    int String:: operator==(const String &other) {
        return (strcmp(ptr, other.ptr) == 0);
        }
    
    String String::operator+(char *s) {
        String new_str(ptr);
        new_str.cat(s);
        return new_str;
        }
   
	String String::operator+(char *s, String *ptr) {
        String new_str(ptr);
        new_str.cat(s);
        return new_str;
        }
    
    // cpy -- Copy string function
    //-------------------------------------
    
    void String::cpy(char *s) {
    delete [] ptr;
    int n = strlen(s);
    ptr = new char[n + 1];
    strcpy(ptr, s);
    }
    
    //cat -- Concatenate string function
    //-------------------------------------
    void String::cat(char *s) {
        int n = strlen(ptr) + strlen(s);
        char *p1 = new char [n + 1];
        
        strcpy(p1, ptr);
        strcat(p1, s );
        
        delete [] ptr;
        ptr = p1;
    }

    
  


But got the errors:

1
2
3
4
5
6
7
1>c:\users\***\documents\visual studio 2010\projects\string_class\string_class\string_class.cpp(23): error C2803: 'operator +' must have at least one formal parameter of class type
1>c:\users\***\documents\visual studio 2010\projects\string_class\string_class\string_class.cpp(39): error C2679: binary '+' : no operator found which takes a right-hand operand of type 'String' (or there is no acceptable conversion)
1>          c:\users\***\documents\visual studio 2010\projects\string_class\string_class\string_class.cpp(23): could be 'String operator +(char *,String *)'
1>          while trying to match the argument list '(const char [12], String)'
1>c:\users\***\documents\visual studio 2010\projects\string_class\string_class\string_class.cpp(79): error C2511: 'String String::operator +(String *)' : overloaded member function not found in 'String'
1>          c:\users\***\documents\visual studio 2010\projects\string_class\string_class\string_class.cpp(7) : see declaration of 'String'
1>


I am quite confused as to why this doesn't work... please help me.

Thank you in advanced!
You need to make your friend operator take a const char pointer, not just a regular pointer. You allso need to define an operator+ that takes a String too.
You need to make your friend operator take a const char pointer, not just a regular pointer. You allso need to define an operator+ that takes a String too.


I tried the first one, didn't work. But what do you mean by a operator+ that accepts a string too? Do you mean one that supports string and char? or one that supports just a string?
You declared the friend function as

friend String operator+(char *s, String *ptr);

but the second parameter shall be an object of type String. So it would be better if it were declared as

friend String operator+(const char *s, const String &ptr);

However as you have already a conversion function that is a non-explicit constructor that have one parameter of type char *

String(char *s);

you could declare only one operator +. Only you have to redeclare your constructor as

String( const char *s);

because string literals have type const char[]

So you have to remove member function operator + and declare only one operator + as a friend function

friend const String operator +( const String &left, const String &right );
Last edited on
I don't understand why but I tried that and it still doesn't work but has a new error:

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
#include <iostream>
#include "stdafx.h"
#include <string.h>

using namespace std;

    class String {
    private:
        char *ptr;
        
    public:
        String();
        String(char *s);
        String(const String &src);
		~String();
        
        String& operator=(const String &src)
                {cpy(src.ptr); return *this; }
        String& operator=(char *s)
                {cpy(s); return *this; }
                

		friend const String operator+(const String &s, const String &ptr);
        int operator==(const String &other);
        operator char*() {return ptr; }
        
        void cat(char *s);
        void cpy(char *s);
        
    };
    
                

int _tmain() {
    String a, b, c;
    a = "I ";
    b = "am ";
    c = "so yeah. ";
    String d = "very happy!" + a + b + "very happy!" + c + "\n";
    cout << d;
    system("PAUSE");
    return 0;
}

//------------------------------------------------------
// STRING CLASS FUNCTIONS

    String::String() {
        ptr = new char[1];
        ptr[0] = '\0';
        }
    
    String::String(char *s) {
        int n = strlen(s);
        ptr = new char[n + 1];
        strcpy(ptr, s);
        }
        
    String::String(const String &src) {
        int n = strlen(src.ptr);
        ptr = new char[n + 1];
        strcpy(ptr, src.ptr);
        }
    
    String::~String() {
        delete [] ptr;
        }
    
    int String:: operator==(const String &other) {
        return (strcmp(ptr, other.ptr) == 0);
        }
    

   
	String String:: operator+(const String &s, const String &ptr) {
        String new_str(ptr);
        new_str.cat(s);
        return new_str;
        }
    
    // cpy -- Copy string function
    //-------------------------------------
    
    void String::cpy(char *s) {
    delete [] ptr;
    int n = strlen(s);
    ptr = new char[n + 1];
    strcpy(ptr, s);
    }
    
    //cat -- Concatenate string function
    //-------------------------------------
    void String::cat(char *s) {
        int n = strlen(ptr) + strlen(s);
        char *p1 = new char [n + 1];
        
        strcpy(p1, ptr);
        strcat(p1, s );
        
        delete [] ptr;
        ptr = p1;
    }

    
 


Error:

1
2
3
4
5
1>c:\users\***\documents\visual studio 2010\projects\string_class\string_class\string_class.cpp(75): error C2039: '+' : is not a member of 'String'
1>          c:\users\***\documents\visual studio 2010\projects\string_class\string_class\string_class.cpp(7) : see declaration of 'String'
1>c:\users\***\documents\visual studio 2010\projects\string_class\string_class\string_class.cpp(75): error C2373: 'operator +' : redefinition; different type modifiers
1>          c:\users\***\documents\visual studio 2010\projects\string_class\string_class\string_class.cpp(23) : see declaration of 'operator +'
1>c:\users\***\documents\visual studio 2010\projects\string_class\string_class\string_class.cpp(77): error C2664: 'String::cat' : cannot convert parameter 1 from 'const String' to 'char *'
Last edited on
First of all instead of

String(char *s);


shall be

String( const char *s);

operator + is not a member of your class, so instead of

1
2
3
4
5
String String:: operator+( const String &s, const String &ptr ); // here is  an error; remove semicolon
        String new_str(ptr);
        new_str.cat(s);
        return new_str;
        }


shall be

1
2
3
4
5
6
const String operator +( const String &s, const String &ptr )
{
        String new_str( s );
        new_str.cat( ptr );
        return new_str;
}




Last edited on
Thank you very much vlad! I took your code and edited a bit and made it:

const String operator +( const String &s, char *ptr ) {

and now it works!

Two questions about the code:

Why don't you have to do the namespace thing for the const String operator + anymore? I thought it would have to be something like: String:: const String operator +

and why is it declared as a friend? I don't see it touching any private members of the class.

Thanks!
Last edited on
Is it your assignment "Rewrite the operator+ function as a global friend function" is not it?

friend functions are not members of befriended classes.

By the way it would be better to define the function as

const String operator +( const String &s1, const String &s2 ) {
Last edited on
const String operator +( const String &s1, const String &s2 ) {

Does not work since it cannot convert from string to char (I got an error for that)

I'm sort of confused about what you mean by "friend functions aren't members of befriended classes"
You have already in your class a conversion function from const char * to String. It is the constructor with parameter const char *. Did you define the constructor String( const char * )?

So when the compiler will see an expression as for example

String a( "Some String" );

a = a + "Another String";

it converts string literal "Another String" to an object of type String by calling constructor String( const char * ).

friend function does not belong to befriended class scope.
Last edited on
friend function does not belong to befriended class scope.


I know that, but what does the friend function access? It accesses private data members, but I don't see it accessing any private members of any class...

(Sorry for my mis-understanding, I've been learning c++ only for a month)
A friend function has access to any member of a befriended class.
Topic archived. No new replies allowed.