0

When I compile the following code,

#include <iostream>
using namespace std;
class class1;//forward declaration

class class1{
int var;
public:
    void setter(int);
    friend void getter(class1 o1);
};

class class2{
public:
    void getter(class1 o1)
    {
        o1.var;
    }
};

void class1::setter(int v)
{
    var =v;
}
int main()
{
    int val;
    class1 o1;
    class2 o2;
    cout<<"Enter value\n";
    cin>>val;
    o1.setter(val);
    cout <<"value:\n"<<o2.getter(o1);
    return 0;
}

I'm getting the following errors, G:\C++ projects\private access specifier\main.cpp|6|error: 'int class1::var' is private| G:\C++ projects\private access specifier\main.cpp|16|error: within this context| G:\C++ projects\private access specifier\main.cpp|32|error: no match for 'operator<<' (operand types are 'std::basic_ostream' and 'void')|

Here I need to access a private member 'var' form class1 with a function 'getter' in class2 I know that there is another simpler way to get & set values but I'm here to understand the working of friend function. Kindly clarify my doubt as I'm new to C++

Meganathan
  • 25
  • 6

3 Answers3

3

The other answers tell you how to solve the problem in the easiest (and probably the best) way. However, if you really want to only grant the friend privilege to single member function, more work is required:

class class1;

// To befriend a member function of class2, it must be defined before the friendship declaration
class class2{
public:
    int getter(class1 o1); 
};


class class1{
    int var;
public:
    void setter(int);
    //correct syntax mentions the class name
    friend int class2::getter(class1 o1);
};

void class1::setter(int v)
{
    var =v;
}

// definition of this function must be after class1 definition, 
// so it can know that `class1` has member `var`
// therefore it cannot be defined inline in class
int class2::getter(class1 o1) 
{
    return o1.var;
}

See it online

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
  • Nice :) Was just thinking of adding this. – cigien Oct 31 '20 at 16:08
  • Are you sure the comments are right? I don't think function parameters have to be complete types, only return types. The parameters don't have to be references/pointers. – cigien Oct 31 '20 at 16:10
  • @cigien Yes, you are right. I was solving compiler errors one by one to reach this and that change wasn't needed. – Yksisarvinen Oct 31 '20 at 16:15
1

This

friend void getter(class1 o1);

Grants friend access to privates of class1 to a free function called getter. There is no such function in your code. class1 can give friend access to class2 like this:

class class2;//forward declaration

class class1{
int var;
public:
    void setter(int);
    friend class2;
};

This also won't compile: cout <<"value:\n"<<o2.getter(o1);. I suppose you want getter to return the value:

class class2{
public:
    int getter(const class1& o1)
    {
        return o1.var;
    }
};
463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
1

In class1, this declaration:

friend void getter(class1 o1);

says that the function getter is a friend of class1.

However, you want a member function of class2 to have access to class1 members. In that case, you can grant friendship to class2 itself, and that will allow member functions of class2 to access private members of class1:

class class2; // forward declaration

class class1 
{
  // ...
  friend class2;
};

Also, note that this line:

cout << "value:\n" << o2.getter(o1);

won't compile since class2::getter returns void which you can't pass to an ostream.

cigien
  • 57,834
  • 11
  • 73
  • 112
  • Is it possible to grant friendship to just a single class member function, or does it have to be granted to the entire class? ETA: Oh, I see Yksisarvinen's answer mentions this. – Nathan Pierson Oct 31 '20 at 16:11
  • @NathanPierson Absolutely. See Yksivarvinen's answer :) – cigien Oct 31 '20 at 16:12