C++: granting member function friendship forward declaration? - c++

I have a problem with friendship in c++. I have two classes, A and B, where the definition of B uses some instance of A. I also want to give a member function within B access to private data members in A, and so grant it friendship. But now, the conundrum is that for the friendship declaration in the definition of class A, class B is as yet undefined, so the IDE (VS 2010) doesn't know what to make of it.
#include <iostream>
using namespace std;
class B;
class A {
friend int B::fun(A A);//B as yet undefined here
int a;
};
class B {
int b;
public:
int fun(A inst);
};
int B::fun(A A)
{
int N = A.a + b;//this throws up an error, since a is not accessible
return N;
}
I have had a look at Why this friend function can't access a private member of the class? but the suggestion there of using a forward declaration of class B; doesn't seem to work. How can I solve this problem directly (i.e. without resorting to making class B a friend of class A, or making B inherited from A or introducing a getA() function)? I have also looked at Granting friendship to a function from a class defined in a different header, but my classes are in one .cpp file (and it would be preferable to keep it that way), not in separate header files, and I do not want to grant the entire class friendship anyway. Meanwhile, C++ Forward declaration , friend function problem provides the answer to a slightly simpler problem - I cannot just change the order of the definitions. Meanwhile, http://msdn.microsoft.com/en-us/library/ahhw8bzz.aspx provides another similar example, but the example fails to run on my computer, so do I need to check some compiler flags or something?

Swap it around?
class A;
class B
{
public:
int fun(A inst);
private:
int b;
};
class A
{
friend int B::fun(A A);
private:
int a;
};
int B::fun(A A)
{ int N = A.a + b;
return N;
}

Related

Acces private static member variable in namespace from another class C++

I have a problem. In the following example, there is a static private member variable called private_b of class A inside namespace a. And then I'm trying to access that variable from class B, which I have declared to be a friend of class A, but it doesn't work, with a compile error from GCC:
error: ‘B* a::A::private_b’ is private within this context
class B;
namespace a {
class A {
private:
static B* private_b;
friend class B;
};
B* A::private_b = nullptr;
}
class B {
public:
void foo() {
B* foo = a::A::private_b; // Error here
}
};
I don't understand why I can't access it, and how to get around this problem. I really want class A to be inside that namespace, and class B doesn't make sense to be inside that namespace. I searched for this on the internet, but couldn't find this exact case, or couldn't find a solution for this case.
friend class B; declared friendship with B in the same namespace a. You may want friend class ::B;.
Note, friend class B; does not refer to the global forward declaration class B, it has own forward declaration class B after the keyword friend.

why declaring an object of a class before defining it gives error in friend class but not in friend function

class B;
class A {
private:
int numA;
public:
A(): numA(12) { }
// friend function declaration
friend int add(A, B);
};
this does not give any error on declaring object of class B in friend
function,,but this gives,,as firstly class B is declared
class Apple;
class B {
private:
int b;
public:
void showA(Apple d)
{
// Since B is friend of A, it can access
// private members of A
cout << "A::a=" ;
}
};
};
this gives an error of incomplete type for object d,,why this is happening though we already declared class apple before,
Why does the first example compile?
In your first example, you have a forward declaration of class B followed by a declaration of a friend function that uses it in its parameter list:
class B;
class A {
...
friend int add(A, B);
};
This is allowed because, although B is incomplete, we are not defining add yet, only declaring an intention to eventually do so.
Why does the second example not compile?
In the second example, we have a forward declaration of class Apple, followed by a definition of showA:
class Apple;
class B {
...
void showA(Apple d)
{
...
}
};
This time, since we are defining the function, the compiler is obligated to generate code for it. But because Apple is incomplete, the compiler cannot know, for example, how much space in memory to reserve to hold the parameter d. Therefore this is an error.
The question When can I use a forward declaration? explains some of what can and cannot be done with an incomplete (forward-declared) type.
The use of 'friend' is irrelevant here
The friend keyword is basically irrelevant here. friend primarily affects access control (in the sense of public and private), but that's not the issue here.
A detail: friend also affects scoping. Because of friend, add is not a member of class A, but rather refers to a member of the global scope without actually introducing one (it's weird). But that does not change whether an incomplete type can be used as a parameter.

c++ how to properly declare friend class method of another class

consider the following example.
class A
{
int member;
};
class B
{
A& a_ref;
void manipulate()
{
a_ref.member++;
}
};
Now, obviously, B::manipulate can not access a_ref. I would like to allow (only) class B to get (reference) to A::member. I know that there exists friend keyword, but I do not know how to use it properly. My intention is, that I could change B::manipulate implementation to become this
int& A::only_B_can_call_this() // become friend of B somehow
{
return member;
}
void B::manipulate()
{
a_ref.only_B_can_call_this()++;
}
To make B a friend:
class A
{
int member;
friend /*class*/ B; // class is optional, required if B isn't declared yet
};
Note that friends are anti-patterns - if something is private, it probably shouldn't be accessed. What are you trying to accomplish? Why isn't A self-contained? Why does another class need to access its internal data?
Use friend if you have valid answers/reasons for these questions.
You simply add friend class <class_name>; to the class that wants to make its members accessible, where <class_name> is the name of the class that you want to provide access for.
class A
{
friend class B; // allow class B to access private members of A
int member;
};
class B
{
A& a_ref;
void manipulate()
{
a_ref.member++;
}
};

Use of friend as "namespace-private" fields or methods

I have a question which is basically the quite opposite of this one.
As we can see in this post, Java does have one more access mode than C++ : package one.
In my code, I would like to make a class that only some other class could instantiate and use, from its own namespace, and not outside. So it looks like a Java "package-privacy access" case, but this option is not available in C++.
My idea to implement it is to make constructor/destructor and most of methods of this class as private or protected, and to give access to other classes from the same namespace with friend keyword.
But, almost everywhere on forums as on my personal talks with other C++ programmers, friend is considered as an evil keyword that destroy every OOP concept and should never be used.
Would it be adequate to use it in this precise case ? Or is there any other solution without friend use ?
When you use friend you won't be able to restrict access to anything private (e.g. member variables).
I may have a better solution.
You define a struct with a private constructor that defines all classes in your "package" as friend.
Then you change the constructor(s) of the classes you want to restrict in access from outside the package to take a reference to that object.
#include <iostream>
#include <vector>
struct code_unlocker
{
friend struct A;
friend struct B;
friend struct C;
private:
code_unlocker() {};
};
struct A
{
A(const code_unlocker&) //Restricted: Only callabble by friends of code_unlocker
{
};
};
struct B
{
B(const code_unlocker&) //Restricted: Only callabble by friends of code_unlocker
{
A a = A(code_unlocker()); //Works
};
};
struct C
{
C()//Accessible from outside
{
B b = B(code_unlocker()); //Works
};
};
using namespace std;
int main(int, char *[])
{
A a = A(code_unlocker()); //Doesn't work
B b = B(code_unlocker()); //Doesn't work
C c = C(); //Works
}

Alternative for forward declaration: two classes using each other

I have class A which has to implement some functions. Since implementing one of them needs it's own data structures, I assumed A contain another class B, which has all needed data structures and functions. However, B is also need to use data structures and functions of A, as well. I used two classes calling each others using forward declaration. But there is still problems. For example, I need to make all data structures in A public, in order to B can access it. I tried using friend classes, but when I declare B as an abstract classes with sub-classes which implements B's functionalities, I need to make all data structures of A, as public. Because friend class doesn't work for inherited sub-classes, all data structures of A, needs to be public. This makes my design quite messy.
class B;
class A{
protected:
int ds[100];
B * b;
public:
a_func(){
b->b_func();
}
};
class A;
class B{
A * a;
public:
b_func(){
a->a_func();
}
};
class sub_B:public B{
public:
b_func(){
a->a_func();
a->ds ...;
}
}
My question is: is there any alternative design?
I also tried making A an abstract class and class B implements a function of it, however, it doesn't conceptually makes sense to build an object of B, when I want an object of A.
You don't have to provide member function definitions inside a class definition:
class A;
class B;
class A {
// no need for public
B * b;
void a_funct(void);
};
class B {
// no need for public here, too
A * a;
void b_funct(void);
};
// the following goes in a source file,
// otherwise you should mark it as inline
void A::a_funct() {
b->b_funct();
}
void B::b_funct() {
a->a_funct();
}
Note that above code serves only as example, in its current shape it's nothing but a fancy endless (recursion) loop.