1

Learning c++ bit by bit in codeblocks, I encountered this error. I have tried it for hours and saw various links but its still not working,

main.cpp

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

using namespace std;

int main()
{
  foo:: Person p;
  //std:: cin >> p;
  std:: cout << p;
  return 0;
 }

Person.h

#ifndef PERSON_H
#define PERSON_H

namespace foo{
class Person
{
   public:
   int age;
   Person();
   friend std:: ostream& operator << (std::ostream&,const Person&);
 //friend std:: istream& operator << (std:: istream& in, Person& p);
   protected:
   private:

  // std::string name;
};

}
#endif // PERSON_H

Person.cpp

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

using namespace foo;

Person::Person()
{
   age = 0;
  //name = "noname";
}


std:: ostream& operator <<(std:: ostream& out, Person const &p)
{
  out << "Extraction operator" << std:: endl << p.age << std:: endl;
  // out << p.name << std::endl;
  return out;
}

/*std:: istream& operator >>(std:: istream& in, Person &p)
{
  in >> p.age >> p.name;
  return in;
}*/

Q1. Why do we need to create the header file and Person.cpp in a seperate namespace? Guess: Is it because cout would simply mean the global namespace and then we again have a overloaded cout so which definition is the compiler going to call its not sure?

Q2. By creating a object p of Person class in foo namespace in main and calling std:: cout << p, what are we trying to do? (std is in std namespace and we want to call the overloaded operator)

Error:

undefined reference to foo:: operator<<(std::ostream&, foo::Person const&)') 

If we write the age in private it says that its is private but being a friend it should have access to private members. I know it's something related to namespace but I can't find out the reason.

no match for operator >> in std::cin Earlier it was giving the above and many other error so I tried using two namespaces but still its not working.

Community
  • 1
  • 1
Rooney10
  • 31
  • 5

2 Answers2

3

You defined operator<< in the global namespace, but declared it inside namespace foo.

Define it inside the namespace foo:

namespace foo
{
    // definition
}
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
  • OP has asked two other questions. – LogicStuff Oct 17 '15 at 17:57
  • @zenith thnx it worked when age is public but if it is private it gives an error int foo::Person::age is private, a friend function should have access to the private members also? – Rooney10 Oct 17 '15 at 18:04
  • @zenith Errors when age and name is declared private : int foo::Person::age is private; std foo::Person::age is private; in>>p.age and in>> p.name error in these two lines. – Rooney10 Oct 17 '15 at 20:32
  • @zenith In your link you did not declare age and name to be private. – Rooney10 Oct 17 '15 at 20:33
  • @Rooney10 `in >>`, you're talking about the other operator, `operator>>`. Declare it `friend` too. – Emil Laine Oct 17 '15 at 21:13
  • i forgot to declare it const, but now it gives a strange ambiguous overload operator for >> in age and name – Rooney10 Oct 17 '15 at 21:15
  • it works when i remove const from const Person& p in the >> operator. – Rooney10 Oct 17 '15 at 21:58
  • and can you please answer my Q1 also why was it necessary to declare the overloaded cin, cout in a separate namespace? – Rooney10 Oct 17 '15 at 22:03
  • Why did you put `const` in `operator>>`? It clearly modifies the `Person`. – Emil Laine Oct 18 '15 at 09:46
  • It's not necessary to put the overloaded `<<` and `>>` in a separate namespace, but it's usually best to put them (and more generally, all functionality related to a class) in the same namespace as the class they were overloaded for (`Person` in this case, which was in `foo::`). – Emil Laine Oct 18 '15 at 09:53
0

I think you using wrong operator declaration

//friend std:: istream& operator << (std:: istream& in, Person& p);

instead of

friend std:: istream& operator >> (std:: istream& in, Person& p);

and also define your class methods in namespace where it were declared

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

namespace foo
{

    Person::Person()
    {
       age = 0;
      //name = "noname";
    }


    std:: ostream& operator <<(std:: ostream& out, Person const &p)
    {
      out << "Extraction operator" << std:: endl << p.age << std:: endl;
      // out << p.name << std::endl;
      return out;
    }

    std:: istream& operator >>(std:: istream& in, Person &p)
    {
      in >> p.age >> p.name;
      return in;
    }

}

the code below runs perfectly on MS Visual C++

#include "stdafx.h"
#include <iostream>
#include <conio.h>
#include <string>

namespace foo{
    class Person
    {
       public:
       Person();
       friend std:: ostream& operator << (std::ostream&,const Person&);
       friend std:: istream& operator >> (std:: istream& in, Person& p);
       protected:
       private:
       int age;
       std::string name;
    };
}

namespace foo
{

    Person::Person()
    {
       age = 0;
       name = "noname";
    }


    std:: ostream& operator <<(std:: ostream& out, Person const &p)
    {
      out << "Extraction operator" << std:: endl << p.age << std:: endl;
      out << p.name << std::endl;
      return out;
    }

    std:: istream& operator >>(std:: istream& in, Person &p)
    {
      in >> p.age >> p.name;
      return in;
    }

}

int main()
{
  foo:: Person p;
  std:: cin >> p;
  std:: cout << p;
  _getch();
  return 0;
 }
Mykola
  • 3,343
  • 6
  • 23
  • 39
  • Thanku for answering, it is solved when it is declared public. Errors when age and name is declared private : int foo::Person::age is private; std foo::Person::age is private; in>>p.age and in>> p.name error in these two lines. – Rooney10 Oct 17 '15 at 20:32
  • friend keyword must deal with private member accessing – Mykola Oct 17 '15 at 20:43
  • it must deal with it... but it gives the above errors, is it something related to namespace access violation? – Rooney10 Oct 17 '15 at 20:53
  • did you mean that `in >> p.age >> p.name;` generate error – Mykola Oct 17 '15 at 20:58
  • yes.. it points to that line and also to that line where name and age were declared private – Rooney10 Oct 17 '15 at 21:00
  • yes i got it ... was it giving an error because i was passing the object as a constant reference and then i was changing the value of the object in the cin ?? – Rooney10 Oct 17 '15 at 22:01
  • and can you please answer my Q1 also why was it necessary to declare the overloaded cin, cout in a separate namespace? – Rooney10 Oct 18 '15 at 04:17
  • It is recomended to place declaration and defenition in separate files because of two reasons: 1) compiler compiles only cpp files (cpp file is a translation unit in c++), so i you compile several translation units witch were compiled previosly compiler will ignore that modules in witch the changes not perform. So the first reason (compile time). 2) If you want to distribute your code as some library (with hidden implementation), you can distribute only header files, and link with your implementation throw some limbrary methods (static, dynamic). So the secont reason (ability to distribution). – Mykola Oct 18 '15 at 09:40