Classes accessing each other

Hi everyone,

So I heard that classes can friend each other, but the only problem is that when I try to do it the compiler won't let me because it says that the forward class wasn't declared. But even if I do this it won't let me:


1
2
3
4
5
6
7
8
9
10
11
  class B{};

  class A
{ friend class B;
//etc
};

  class B
{
    //etc....
};



So how do you actually do this? How do you make a forward declaration of a class and how do you friend classe?
closed account (LA48b7Xj)
You code don't doesn't work because you are defining class B at the top. just remove the braces.
Last edited on
ohhh I see.
Thanks!
But now what do I do if I want to friend only one function in another class?
I believe I should do something like:

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

class B;

class A

{
public:
    friend B::funct(A&z);
    int getx(){return x;}
private:
    int x=0;
};

class B
{
public:
    void funct(A&z){z.x=1;}
private:
    int y=0;
};


But then the compiler says:
Invalid use of incomplete type class B
anyone?
Well there are a few problems with your code. First of all, you forward declare B which might look fine at first but then you try to access a function in class B when the class hasn't actually been defined. Second of all, when befriending a function you must specify the complete type, as in specifying the return of the function. After this you run into another problem, which is that you are trying to access an incomplete class, class A. To which, this problem can be solved by defining the functions after the class or via header files and cpp files.

Solution 1
main.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
#include <iostream>

class A;


class B {
public:
	void funct(A&z, int newValue);
private:
	int y = 0;
};

class A {
public:
	friend void B::funct(A&, int);

	A(int value) { x = value; }

	int getx() { return x; }

	void setX(int value) { x = value; }
private:
	int x;
};

void B::funct(A& z, int newValue) {
	z.x = newValue;
}
int main() {
	int value;

	std::cout << "Enter value for a: ";
	std::cin >> value;

	A a(value);
	B b;

	std::cout << "Current value of a: " << a.getx() << "\n\n";
	std::cout << "Enter new value for a: ";
	std::cin >> value;

	b.funct(a, value);
	std::cout << "Final value of a: " << a.getx() << "\n\n";

	std::cin >> value;
	return 0;
}


B.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef B_H
#define B_H

//Forward declare class A
class A;

class B
{
public:
	B();
	~B();
	void editA(A& a, int newValue);
};

#endif


B.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "B.h"
#include "A.h" //include a in the cpp, fixes declaration issue.


B::B()
{
}

B::~B()
{
}

void B::editA(A& a, int newValue)
{
	//edit the value of a since we have access.
	a.m_value = newValue;
}


A.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef A_H
#define A_H
#include "B.h" //Include B since we need to access the complete type.

class A
{
private:
	int m_value;
public:
	//Friend a function of class B, notice complete type.
	//Also notice how we do not necessarily need to specify argument names but just types.
	friend void B::editA(A&, int);
	A(int value);
	~A();

	int getValue() const;
};

#endif 


A.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "A.h"

A::A(int value)
{
	m_value = value;
}

A::~A()
{
}

int A::getValue() const
{
	return m_value;
}


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include "B.h"
#include "A.h"

int main() {
	int value;

	std::cout << "Enter value for a: ";
	std::cin >> value;

	A a(value);
	B b;

	std::cout << "Current value of a: " << a.getValue() << "\n\n";
	std::cout << "Enter new value for a: ";
	std::cin >> value;

	b.editA(a, value);
	std::cout << "Final value of a: " << a.getValue() << "\n\n";

	std::cin >> value;
	return 0;
}
Last edited on
Ok I see. Thanks.
So globally it's much easier to simply have a class access a whole class and not just a member function...
Topic archived. No new replies allowed.