Making member function, friend of a class - c++

I've been trying to write up a code to implement a member function that could access private data of a class by declaring it as a friend within the class. But my code is failing and I can't seem to figure out what's wrong with it:
#include <iostream>
using namespace std;
class A;
class B
{
private:
int b; // This is to be accessed by member function of A
public:
friend void A::accessB();
};
class A
{
private:
int a;
public:
void accessB();
};
void A::accessB()
{
B y;
y.b = 100;
cout << "Done" << endl;
}
int main(void)
{
A x;
x.accessB();
}
I am trying to access the private contents of B making use of getAccessB function which is member function of A. I have declared it as a friend. What's wrong with this?

A::accessB is not declared at the point of the friend declaration, so you can't refer to it. You can fix this by shifting the order of definitions and declarations such that A::accessB is visible to B:
class A
{
private:
int a;
public:
void accessB();
};
class B
{
private:
int b;
public:
friend void A::accessB();
};
void A::accessB()
{
B y;
y.b = 100;
cout << "Done" << endl;
}
Note that making a function a friend just so that it can modify your private state is a bad code smell. Hopefully you are just doing this to understand the concepts.

The ordering. If you are referring to A::accessB, A must be declared by that point. Place the A class above the B, and it will work fine.

Related

Difference between friend function and getters

I'm currently new to OOP concepts of C++ language like friend of the function and friend of the class .
May be this is not he best comparision between freinds and getters but for the example below:
#include <iostream>
using namespace std;
class ClassB; // forward declaration
class ClassA
{
int numA;
friend int add(ClassA, ClassB); // friend function declaration
public:
ClassA() : numA{12} {} // constructor to initialize numA to 12
};
class ClassB
{
int numB;
friend int add(ClassA, ClassB); // friend function declaration
public:
ClassB() : numB(1) {}
};
// access members of both classes
int add(ClassA objectA, ClassB objectB)
{
return objectA.numA + objectB.numB;
}
int main()
{
ClassA objectA;
ClassB objectB;
cout << "Sum: " << add(objectA, objectB);
return 0;
}
what if i simply use getter to get the values and add them. The main moto of friend function is to access the private and public data members (i guess) , and getters are already doing this .
I'm quite confused here.
There is an excellent talk about this subject here: CppCon 2017: Klaus Iglberger “Free Your Functions!”
My take-away is that if a member function needs no access to the internals of a class, then it should not be a member function. In your case, how will Class A be usable? It is not right now, but I imagine you will have something like explicit operator int() const or int get_val() const. You can simply use this in a free function:
A operator+(A lhs, B rhs) {
return A{lhs.get() + rhs.get()};
}
B operator+(B lhs, A rhs) {
return B{lhs.get() + rhs.get()};
}
int main() {
...
cout << "sum: " << (objectA + objectB).get() << "\n";
...
Or something similar.

how to call another class's member function?

I have two class, class A, Class B, in class B has a static function like below:
class A {
public:
void method(){ B::method(); }
};
class B {
public:
static int method() {
cout << "method of b" << endl;
}
};
int main()
{
class A a;
a.method();
}
this code build error, because in class A, B is not be declared, but I want class A be defined earlier than class B, how should i do? I was thought it may need forward declaration, but it seems not this reason...
Take a look at the modified code. Inline comments explain the changes:
class A {
public:
// only declare the method
void method();
// Do NOT define it here:
// { B::method(); }
};
class B {
public:
static int method() {
std::cout << "method of b" << std::endl;
return 0;
}
};
// and now, as B implementation is visible, you can use it.
// To do this, you can define the previously declared method:
void A::method() { B::method(); }
int main()
{
class A a;
a.method();
}
Hint: Please never use using namespace std

C++ Change private member of a class through only one other specific class?

How do I change the int 'a' inside class A but restrict the function that changes the int to ONLY class B? I do not even want A to be able to change it.
I have tried to create a friend function, but I get an error I included in the comments of the code. I then tried to just forward declare the function as a friend function in private and then actually creating the function in public, but the C class can access the public function. This despite me writing (in the private section) that the function is a friend function. Can I 'friend' a private value? I am unsure what to do here.
#include <stdio.h>
#include <iostream>
int main() {
// forward declaration
class B;
class C;
class A {
private:
int a; // private member I want to edit, but only via class B.
int a2; // I would like to NOT be able to access this in class B. I only want to access and modify int a from class B, no other variable. If possible.
// invalid use of non-static data member 'a'
friend void test(int new_value) {
a = 5;
}
friend B;
public:
};
class B {
private:
int b;
public:
change_a_value(A a_class, int new_int) {
a_class.test(new_int); // I want this to be possible.
}
};
class C {
private:
int c;
public:
change_a_value(A a_class, int new_int) {
a_class.test(new_int); // I want this to be impossible
}
};
return 0;
}
Add "void" before prototypes of change_a_value, and change the
friend B
to
friend class B
and suppress friend in
friend void test(int new_value) {
complete corrected program :
int main() {
// forward declaration
class B;
class C;
class A {
private:
int a; // private member I want to edit, but only via class B.
int a2; // I would like to NOT be able to access this in class B. I only want to access and modify int a from class B, no other variable. If possible.
void test(int new_value) {
a = new_value;
}
friend class B;
public:
};
class B {
private:
int b;
public:
void change_a_value(A a_class, int new_int) {
a_class.test(new_int); // I want this to be possible.
}
};
class C {
private:
int c;
public:
void change_a_value(A a_class, int new_int) {
a_class.test(new_int); // I want this to be impossible
}
};
return 0;
}
Compilation results are what was expected :
TestCpp2.cpp:9:14: error: ‘void main()::A::test(int)’ is private
void test(int new_value) {
^
TestCpp2.cpp:28:31: error: within this context
a_class.test(new_int); // I want this to be impossible
^
Makefile:510: recipe for target 'TestCpp2.o' failed
make: *** [TestCpp2.o] Error 1

Can't spot the mistake in using "friend" function of another class C++

Yes I know that private modifier created in order to prohibit access to class data
but isn't friend intended to allow special access to it?
Compiler:
main.cpp: In member function 'void C::blah(B&)':
main.cpp:48:26: error: 'int B::a' is private within this context
std::cout << obj.a << std::endl;
Everything below is implemented the way as it is in many tutorials.
May be it's just a silly mistake I made and blind to spot.
class C;
class B {
private:
int a = 2;
public:
friend void blah(B& obj);
};
class C {
public:
void blah(B& obj) {
std::cout << obj.a << std::endl; //*
}
};
*Member B::a is inaccessible
You're declaring a non-member function named blah, but not C::blah as friend.
You could change your code to the following, and note the order of the declaration and definition.
class B;
class C {
public:
void blah(B& obj);
};
class B {
private:
int a = 2;
public:
friend void C::blah(B& obj);
};
void C::blah(B& obj) {
std::cout << obj.a << std::endl;
}
LIVE

Why do I get an error with my usage of C++ friend functions?

I'm trying to learn friend function in C++, despite defining display() as a friend function, it's unable to access variable a and b. That's why compiler is showing error.
Who is display supposed to display? Being friend just means that if you run across an object of that class you can access all its innards. You probably want:
void display(const Add &a) {
cout << a.a + a.b;
}
And then you can call it in main with:
display(A);
(remember you'll need to change the definition of display in the class too!)
For better explanation friend function is for accessing private or protected attributes of the class from outside (that it shouldn't reach without proper accessors). A better explaining answer can be found at
Example taken from programiz:
#include <iostream>
using namespace std;
// forward declaration
class B;
class A {
private:
int numA;
public:
A(): numA(12) { }
// friend function declaration
friend int add(A, B);
};
class B {
private:
int numB;
public:
B(): numB(1) { }
// friend function declaration
friend int add(A , B);
};
// Function add() is the friend function of classes A and B
// that accesses the member variables numA and numB
int add(A objectA, B objectB)
{
return (objectA.numA + objectB.numB);
}
int main()
{
A objectA;
B objectB;
cout<<"Sum: "<< add(objectA, objectB);
return 0;
}
on normal cases that add function out of the classes shouldn't reach numA or numB attributes since they are private but since it is declared as friend it gives no error. So on your problem you should do it like this:
#include<iostream>
using namespace std;
class Add {
private:
int a, b;
/*Declared as private to show the significance of friend otherwise
*it does not make sense*/
public:
void get_data();
friend void display(Add);
}
//And change the display function
void display(Add obj) {
cout << (obj.a + obj.b);
}