overloading << operator

Hi guys,

I'm trying to overload the << operator for my book class but to no avail it must be something simple,but I get an error is there something wrong with my syntax,

must you declare this function outside the class?

thanks

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
  class Book{

private:
    string name;
    string ISBN;
    string author;
    string defaultISBN = "000-000-000-F";
    string defaultName = "Default";
    bool checkedOut;

public:

    Book(string name,string ISBN,string author)
    :name(name),ISBN(ISBN),author(author),checkedOut(false)
    {
       if(!validISBN(ISBN)){

        ISBN = defaultISBN;
        cout << "not a valid ISBN, defaulting the ISBN to : " << defaultISBN << endl;
       }
       if(!validAuthor(author)){

         author = defaultName;
         cout << "not a valid name,defaulting the author to :" << defaultName << endl;
       }
    }

    string getName(){ return name;}
    string getISBN(){return ISBN;}
    string getAuthor(){return author;}
    bool isCheckedOut(){return checkedOut;}
   

    ostream& operator<<(ostream& os){

    os << name << " : " << author << " : " << ISBN << endl;
    return os;
    }

// note I excluded some functions such as validAuthor and validISBN from the code to focus on just the operator << function,rest of code compiles fine without the function 


  int main()
{
     Book b("fire","12-13-3478-E","Jim");
     b.validISBN("172-13-7474-G");
     Book c("water","12-13-3478-B","Bob");

     if(b == c){

        cout << "same ISBNS" << endl;

     }
      cout << c << endl;

}
Last edited on
The ostream operator<< should either be a friend function or it can be a "free" function implemented outside your class if it can use public methods to access any private data inside the class. It will also require two parameters, the stream and an instance of your class.

By the way why do you have variables that are basically the same?

1
2
3
    string ISBN;
    ...
    string defaultISBN = "000-000-000-F";


What is the purpose of the "default", why not just assign that "default" to ISBN?


thanks jlb I will try that :)

the reason I have a default ISBN is if the user enters a wrong ISBN well wrong formatted ISBN

I will post all of the code for the fun of it lol it may need some more tweaking,note I added a genre type to the class


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

#include <iostream>

using namespace std;

enum Genre{

   FICTION = 1,
   HORROR,
   CRIME,
   DRAMA,
   SCIFI,
   THRILLER,
   BIO
};

class Book{

private:
    string name;
    string ISBN;
    string author;
    Genre genre;
    string defaultISBN = "000-000-000-F";
    string defaultName = "Default";
    bool checkedOut;


public:

    Book(string name,string ISBN,string author,Genre genre)
    :name(name),ISBN(ISBN),author(author),checkedOut(false),genre(genre)
    {
       if(!validISBN(ISBN)){

        ISBN = defaultISBN;
        cout << "not a valid ISBN, defaulting the ISBN to : " << defaultISBN << endl;
       }
       if(!validAuthor(author)){

         author = defaultName;
         cout << "not a valid name,defaulting the author to :" << defaultName << endl;
       }
    }

    string getName(){ return name;}
    string getISBN(){return ISBN;}
    string getAuthor(){return author;}
    bool isCheckedOut(){return checkedOut;}
    void checkOutBook(){

      if(checkedOut){

        cout << "sorry book already checked out" << endl;
      }else{

          checkedOut = true;
      }
    }
    void returnBook(){
       checkedOut = true;
    }

    bool operator==(const Book& other){

       return ISBN == other.ISBN;
    }

    bool operator!=(const Book& other){

       return !(ISBN == other.ISBN);
    }

    ostream& operator<<(ostream& os){

    os << name << " : " << author << " : " << ISBN << endl;
    return os;
    }

    bool validISBN(string i){

       int second;
       int third;
       int fouth;
       int fifth;

       for(int j = 0; j < i.size(); j++){

        if(i.at(j) == '-'){

            second = j;
            break;
         }
         if(!isdigit(i.at(j))){

            return false;
         }
       }

       for(int j = second+1; j < i.size(); j++){

         if(i.at(j) == '-'){

            third = j;
            break;
         }
         if(!isdigit(i.at(j))){

            return false;
         }
       }

       for(int j = third+1; j < i.size(); j++){

         if(i.at(j) == '-'){

            fifth = j;
            break;
         }

         if(!isdigit(i.at(j))){

            return false;
         }
       }

     for(int j = fifth+1; j < i.size(); j++){

        if(i.at(j) == '-'){

            return false;
        }

        if(isdigit(i.at(j))){

            return false;
         }
     }
     return true;
    }

    bool validAuthor(string n){

      for(int i = 0; i < n.size(); i++){

        if(isdigit(n.at(i))){

            return false;
        }
        return true;
      }
    }
};

int main()
{
     Book b("fire","12-13-3478-E","Jim",HORROR);
     b.validISBN("172-13-7474-G");
     Book c("water","12-13-3478-B","Bob",THRILLER);

     if(b == c){

        cout << "same ISBNS" << endl;
     }
}
the reason I have a default ISBN is if the user enters a wrong ISBN well wrong formatted ISBN

What? If the user enters the wrong ISBN then just assign the "Default" to ISBN there is no need for the default. Also if the user enters the wrong ISBN then the rest of the data should be some meaningful default as well.

You still haven't fixed the problem with the ostream operator overload. Remember that you are overloading std::ostream with this overload not your class.

Topic archived. No new replies allowed.