Operator<< Overloading

I'm doing an assignment for my OOP class, and I am a little confused about the use of operator overloading. I've seen a few examples, but not using the operator<<, and I don't quite get how this works. Here is the part I'm having trouble with:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

ID::ID()                                                                   
{                                                                                    
    SetName("#");
    
    SetAge(-1);

};  

ID::ID ( const char * name, int age )
{
    SetName(name);
    
    SetAge(age);
    
};


I have included the following in my public class declaration:

 
friend std::ostream &operator<<(std::ostream &, ID &);


And I need to be able to output what is passed into the constructor using the following:
1
2
3
ID p1, p2("Jane Doe", 25);
std::cout<< " p1 = " << p1 << '\n';
std::cout<< " p2 = " << p2 << '\n';


This should read:
1
2
p1 = #     -1
p2 = Jane Doe  25


I am confused about the operator overloading part, and right now I'm getting a linker error saying:

Undefined symbols for architecture x86_64:
"operator<<(std::ostream&, ID&)", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)


Any help or a push in the right direction would be greatly appreciated. Thanks in advance.

**Update**
And now Im extra confused, I just realized that I'm not allowed to use 'friend', so I went back and changed the line in my header file to:
 
std::ostream &operator<<(std::ostream &output, ID &p1);


but now I'm getting "Overloaded 'operator<<' must be a binary operator(has 3 parameters)"
What now?
Last edited on
#include <iostream>

using namespace std;

class ID
{
public:
ID::ID()
{
SetName("#");
SetAge(-1);
}

ID::ID(const char * name, int age)
{
SetName(name);
SetAge(age);
}

void SetName(const char* name)
{
strcpy(this->name,name);
}

void SetAge(int age)
{
this->age = age;
}

friend ostream& operator<<(ostream&, ID&);

private:
char name[BUFSIZ];
int age;
};

ostream& operator<<(ostream& cout, ID& id)
{
cout << id.name << ' ' << id.age << endl;
}

int main(void)
{
ID p1, p2("Jane Doe", 25);

cout << " p1 = " << p1 << endl;
cout << " p2 = " << p2 << endl;

return 0;
}


[root@admin shm]# c++ op.cpp && ./a.out
p1 = # -1

p2 = Jane Doe 25

[root@admin shm]#
Thanks, but I'm still getting the same error as before. If I comment out the
 
friend std::ostream &operator<<(std::ostream &, ID &);

it works for p1, but when I get to p2 it doesn't work there.
Could you show me your full source code here, then I could help you to figure it out ?
Last edited on
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
#ifndef id_h                                                                               
#define id_h                                                                               

#include <iostream>  
#include <cstring>




class ID                                                                                   
{                                                                                        
public:                                                                                  
    
    ID();
    
    ID ( const char * name, int age );

    
    void SetName ( const char* );                                                          
    
    void SetAge ( int );                                                                   
    
    const char* GetName () const;                                                          
    
    int GetAge () const;  
    
    friend std::ostream &operator<<(std::ostream& cout, ID &);
 
    //std::ostream& operator << (std::ostream& os,const ID& p1);
    
    
    
private:                                                                                 
    
    char * name_;                                                                          
    
    int age_;                                                                              
    
    
};                                                                                         


#endif 


id.cpp:
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
#include <iostream>                                                                    
#include "id.h" 
#include <cstring>
#include <iomanip>




ID::ID()                                                                   
{                                                                                    
    std::cout << "Hello default constructor." << std::endl; 
    
    
	SetName("#");
    
    SetAge(-1);

     std::cout << "\nGoodbye default constructor" << std::endl; 
};  


ID::ID ( const char * name, int age )
{
    SetName(name);
    
    SetAge(age);
    
    ID p1;
    
    

    
    std::cout << name << age << std::endl;
    
};

void ID::SetName ( const char * name )                                                         
{                                                                                    
    //name = name_;
    
    strcpy(this->name_, name);
}     



void ID::SetAge ( int age )
{
    this->age_ = age;
}


main:

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
#include <cstdlib>                                                                         
#include <iostream>                                                                        
#include <iomanip>                                                                         
#include "id.h"                                                                           
//#include "id.cpp" // in lieu of makefile                                                 


const size_t arraySize = 10;                                                               
const size_t numDigits = 2;                                                                

//ID CopyCheck (ID id)  // pass in by value calls CC                                         
//{                                                                                          
//    ID x = id;  // initialization calls CC (NOT assignment!)                                 
//    return x;   // return by value calls CC                                                  
//}                                                                                          

int main()                                                                                 
{    
    
    ID p1; 
    ID p2("Jane Doe", 100);                                                          
    std::cout << " IDs after declaration:\n";                                                
    std::cout << "  p1 = " << p1 << '\n';                                                    
    //std::cout << "  p2 = " << p2 << '\n';                                                    
    
    //p1.SetName("John Smith");                                                               
    //p1.SetAge(21);                                                                           
    //p2.SetName("Chris White");                                                                
    //p2.SetAge(21);                                                                           
    //std::cout << " IDs after Set:\n";                                                        
    //std::cout << "  p1 = " << p1 << '\n';                                                    
    //std::cout << "  p2 = " << p2 << '\n';                                                    
    
    //p1 = CopyCheck(p2);                                                                      
    //std::cout << " IDs after p1 = CopyCheck(p2):\n";                                         
    //std::cout << "  p1 = " << p1 << '\n';                                                    
    //std::cout << "  p2 = " << p2 << '\n'; 
    
    
    //ID p3 ("Assignment Check", 50);                                                          
    //p1 = p2 = p3;                                                                            
    //std::cout << " IDs after p1 = p2 = p3:\n";                                               
    //std::cout << "  p1 = " << p1 << '\n';                                                    
    //std::cout << "  p2 = " << p2 << '\n';                                                    
    //std::cout << "  p3 = " << p3 << '\n';                                                    
    
   /* ID * idarray = new ID [arraySize];                                                       
    std::cout << " ID Array after declaration:\n";                                           
    for (size_t i = 0; i < arraySize; ++i)                                                   
    {                                                                                        
        std::cout << "  id[" << std::setw(numDigits) << i << "] = " << idarray[i] << '\n';     
    } */                                                                                       
    
    
    //for (size_t i = 0; i < arraySize; ++i)                                                   
    //{                                                                                        
      //  idarray[i].SetName("A. B. Student");                                                   
        //idarray[i].SetAge(17 + i);                                                             
    //}                                                                                        
    //std::cout << " ID Array after Set:\n";                                                   
    //for (size_t i = 0; i < arraySize; ++i)                                                   
    //{                                                                                        
      //  std::cout << "  id[" << std::setw(numDigits) << i << "] = " << idarray[i] << '\n';     
    //}                                                                                        
}  


You can pretty much ignore whatever is not revelant to this problem, I haven't gotten very far with it yet, so I'm sure there's still a lot for me to work out on my own if I can get past this part. The main was supplied by the instructor, as well as the prototypes for SetName, SetAge, GetName, GetAge, and variables name_ and age_, so none of that can be altered. My problem lies with the constructors, and operator overloading I believe. And I didn't realize until after I posted, but I am not allowed to use 'friend' so I have to find a way to remove that. Assignment operator<< should be overloaded with type ID.
the problem is that char *name_ is a wild pointer.

you have already defined get/set interface for your private members of the ID class, so the keyword friend is utterly unnecessary.

BTW, i am not sure the purpose of the ID p1; statement in the second constructor -:)
Last edited on
Thank you very much for helping me. :)

Oops, the ID p1 line was an idea I had gone wrong, and I forgot to remove it.

So this means I should initialize char_ right?

Also, the
std::ostream& operator << (std::ostream& os,const ID& p1);
line still does not work, I get "Overloaded 'operator<<' must be a binary operator(has 3 parameters)' What does this mean? I tried adding another parameter, and it gave me the same message, only it said 4 parameters. I'm getting that line straight out of my book, so I don't see why I'm getting this error.
you'd initialize char *_name definitely.

that means you give too much parameters, you got reverse tries, aha, the compiler tell you operator<< must be a BINARY operator, that means this operator overload method can only accept two parameters, try again to check it out!
Last edited on
Ok so I'm working on getting char_ * initialized, but I still don't get the operator overload...there are only 2 parameters there, right? stream& os, and const ID& p1?
you must assure the declaration information in the header file must match the definition information in cpp file, could you paste the definition of std::ostream& operator << (std::ostream& os,const ID& p1) here ?
Last edited on
1
2
3
4
5
std::ostream &operator<<(std::ostream &output, ID &p1)
{
    output << p1.GetName() << "     " << p1.GetAge();
    return output;
}


.h file:
std::ostream &operator<<(std::ostream &output, ID &p1);

I'm getting the error in .h, same error message. It doesn't even recognize it in .cpp
AHA!! Had the definition inside the definition of the class. Put it outside the class definition, and that error goes away, but it still doesn't like my definition.....now I'm getting linker errors:

Undefined symbols for architecture x86_64:
"ID::GetName() const", referenced from:
operator<<(std::ostream&, ID&) in id.o
"ID::GetAge() const", referenced from:
operator<<(std::ostream&, ID&) in id.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I got it. std::ostream &operator<<(std::ostream& cout, ID &) must add friend keyword if within class definition. otherwise, omit it from the class definition.
I almost sure that you forgot add const keyword at the definition place of GetName() & GetAge().
Last edited on
Figured that one out...that was an oopsie on my part...still had them commented out. I think I can take it from here. Thank you so much for all your help, you probably saved me hours of headaches!
sure, good luck, you guy...
Topic archived. No new replies allowed.