c++oopfriend-class

no match for ‘operator>>’


I am trying to implement friend class. When I try to run code I get errors like .

a3.cpp:85:5: error: `no match for ‘operator>>’` (operand types are ‘std::istream {aka std::basic_istream<char>}’ and ‘int*’)
  cin>>this->telephone_number;
     ^
a3.cpp:85:5: note: candidates are:
In file included from /usr/include/c++/4.8/iostream:40:0,
             from a3.cpp:9:
/usr/include/c++/4.8/istream:120:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__istream_type& (*)(std::basic_istream<_CharT, _Traits>::__istream_type&)) [with _CharT = char; _Traits = std::char_traits<char>; std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>]
   operator>>(__istream_type& (*__pf)(__istream_type&))

My Code:

#include <iostream>
#include <string.h>
using namespace std;

class PI
{
    private: 
            string *name;                               //dynamic allocation

            static int count;                                                        //static memeber
    public:
            PI();                                    //default constructor
            //void getdata();

            inline static void displaycount()       //inline static member function PI::displaycount()
            {
                cout<<"\nCandidate Count: "<<count;
            }            

            ~PI()                                   //destructor
            {
                cout<<"DESTRUCTOR CALLED";
            }
            PI(PI &);                               //copy constructor
            friend class PI1;  
};

class PI1
{
    private:
            int *height, *weight,*telephone_number;
    public:
            PI1(PI &);
            void getdata(PI &);
            void putdata(PI &);     


};

int PI :: count = 0;
PI :: PI()
{
    name = new string();
    count=count+1;
}
PI1 :: PI1(PI)
{
    height = new int;
    weight = new int;

    telephone_number = new int;

    obj.count=obj.count+1;
}

void PI1 :: getdata(PI &obj)
{
    //cin.ignore();
    cout<<"\nEnter Name: ";
    getline(cin,obj.name);

    cout<<"\nEnter Height: ";
    cin>>this->height;
    cout<<"\nEnter Weight: ";
    cin>>this->weight;

    cout<<"\nEnter Telephone Number: ";
    cin>>this->telephone_number;

}

void PI1 :: putdata(PI &obj)
{

    cout<<"\nName: "<<obj.name;

    cout<<"\nHeight: "<<this->height;
    cout<<"\nWeight: "<<this->weight;

    cout<<"\nTelephone Number: "<<this->telephone_number;


}

int main()
{
    PI p;
    PI1 p1(p);

    p1.getdata(p);
    p1.putdata(p);
    PI :: displaycount();
    return 0;
}

Solution

  • Because name, height, weight and telephone_number are pointer, you should make an indirection. So you should write:

    getline(cin,*(obj.name));
    cout<<"\nEnter Height: ";
    cin >> *(this->height);
    cout<<"\nEnter Weight: ";
    cin >> *(this->weight);
    cout<<"\nEnter Telephone Number: ";
    cin >> *(this->telephone_number);
    

    And also, everywhere you need to get or set value of those fields, you should use indirection. Read about pointers and its used (here or here for example)


    And I think you don't need to use pointer inside your class. It's error prone! Just use directly data, ie:

    class PI
    {
        private: 
                string name;   
    ....
    

    and

    class PI1
    {
        private:
            int height, weight, telephone_number;
    

    You will have no memory to manage by yourself, so less of possible bug.


    But if you really need that, take a look at smart pointer which respect RAII: std::shared_pointer or boost::shared_pointer, std::unique_pointer or boost::unique_pointer