Friends and nested classes - c++

Ok I'm totally frazzled on this. Code is begin to swim around the screen...must sleep.
So! Ok, troubled by nested classes and friends.
here is the pseudo-code
class A{
public:
//constructor
// member functions
private:
class B{
//private
int a();
};
class C{
//private
int b();
};
};
So once an object of type A has been created, I would like it to access a() and b(). I know that I have to use a friend function for this. So where should I put friend class A. Is that the right expression?.

If you would like to access a() and b() from within class A you need to place the friend declaration inside of class B and class C. However, a() and b() are not members of class A so you cannot access them in the way you are thinking. Instead you also need to add forwarding functions to A.
class A
{
public:
//constructor
// member functions
private:
class B
{
//private
int a();
friend A; // <-- make A a friend
};
class C
{
//private
int b();
friend A; // <-- make A a friend
};
public:
// forwarding function for a
int a()
{
return bdata_.a();
}
// forwarding function for b
int b()
{
return cdata_.b();
}
private:
B bdata_;
C cdata_;
};

Related

Why Friend Function cannot access private members of a class

class A{
public:
void printer(){
B obj;
obj.private_data = 10; // <- fails, says member inaccessible
}
}
class B{
friend void A::printer();
private:
int private_data;
}
is it possible for printer function to access private members of class B? i tried to pass an obj of B as arg to printer but it still failed
Class A doesn't know about B to use it. Hence, postpone the definition of the function printer() until you define B, and if you need an instance of B to be a member var in A then make a forward declaration for B to declare a B* in A.
Hence, use something like what follows:
class A {
public:
void printer();
};
class B {
friend void A::printer();
private:
int private_data;
};
void A::printer() {
B obj;
obj.private_data = 10; // <- No longer fails
std::cout << obj.private_data;
}
int main() {
A a;
a.printer();
}
Demo
Why Friend Function cannot access private members of a class?
They can, but you may need to split the definition of the class up a bit.
Imaginary files added:
Define A (file a.hpp):
class A {
public:
void printer();
};
Define B (file b.hpp):
#include "a.hpp" // B must see the definition of A to befriend a member function
class B {
friend void A::printer();
private:
int private_data;
};
Define A's member function (file a.cpp):
void A::printer() {
B obj;
obj.private_data = 10;
}
To access B, you first need to define it. Thus, you can just declare the method printer and define it after you have defined the class B.
class A {
public:
void printer();
};
class B {
private:
friend class A;
int private_data;
};
void A::printer() {
B obj;
obj.private_data = 10;
}
Note, you probably want to move your methods out of your class definition anyways and into a separate .cpp file. Methods defined inside the class are implicitly marked as inline which might not be what you expect.

How to access the class member

Sorry for the bad title... I think the solution may exist on this site, but I cannot find it.
class A {
};
class B {
private:
int _b;
};
class C {
private:
A a; // a: I want to access _b in b
B b;
};
Let's say I have 3 classes like the code above, now the object a in class C wants to access the member _b in object b. Is there any method to achieve it?
I tried using friend, I wonder if I haven't used it in a proper way, because it made the code very complex, like this:
class B {
private:
int _b;
public:
B() : _b(5) {}
int get_b() {
return _b;
}
};
class A {
public:
int get_a(B& b) {
cout << b.get_b();
}
};
class C {
private:
friend class A;
A a;
B b;
public:
A& get_A() {
return a;
}
B& get_B() {
return b;
}
};
int main() {
C c;
c.get_A().get_a(c.get_B());
}
Thank you in advance.
EDIT
Sorry about the confusing code above, actually I want to implement a compiler using OO style. I think a compiler is made of lexer, parser, and symbol table and other things. So I think the relationship is:
class compiler {
private:
lexer l;
parser p;
symbol_table st;
...
};
And the parser and lexer need to access the symbol_table, that is why this question is put forward. I think this design is resemble to the real compiler "in my opinion", but it seems hard to implement... Any advice is appreciated.
In you example, A must be a friend of B and not of C to let it access members of B:
class A;
class B {
friend class A;
//...
};
// ....
In other terms, it should look like this:
#include<iostream>
using namespace std;
class A;
class B {
friend class A;
private:
int _b;
public:
B() : _b(5) {}
};
class A {
public:
int get_a(B& b) {
cout << b._b;
}
};
class C {
private:
A a;
B b;
public:
A& get_A() {
return a;
}
B& get_B() {
return b;
}
};
int main() {
C c;
c.get_A().get_a(c.get_B());
}
That being said, you should probably reconsider your design to avoid such a strong dependency between your classes and get rid of friends.
Your code looks really confused. I'm not sure what you are trying to do in the second piece of code. The only place you can enable access to members of class B is in class B. You can do this either through making those members public or protected, adding accessor functions for the members or setting another class to be a friend class of class B by adding a friend class declaration inside class B.
Personally I would go with accessor functions as this means you are reducing class to class dependencies. Any class that has internal access to class B, by being made a friend or having direct access to member variables because they are public, is then dependent on the structure of class B.

How do I access a private constructor in a separate class?

I'm writing a library in C++. I have two classes in my library, A and B. I want to hide the A() constructor from any code that references my library. I also want class B to be able to call the A() constructor.
I come from a C# background and remember little of my C++. In C#, I would simply declare the A() constructor as internal. I've read that the closest way to do this in C++ is a combination of friend declarations and forward-declarations. How do I do this? Here are my three files below:
A.h:
#pragma once
class A
{
private:
A();
};
B.h
#pragma once
class A;
class B
{
public:
A createA();
};
B.cpp:
#include "A.h"
#include "B.h"
A B::createA()
{
A result; //cannot access private member declare in class 'A'
return result;
}
I've tried adding this to A.h:
public: friend A createA();
I've instead tried adding this to A.h with a corresponding forward declaration:
public: friend A B::createA();
I've instead tried adding and extern class B; to A.h and making B a class like this:
public: friend class B;
I'm at a loss.
I think this might be easier if I have the B::createA() function return a pointer to an A object rather than an A object directly, but that won't do in my case. I am emulating a closed API and the API call returns an A object rather than a pointer.
You probably just need to drop the "extern" from your third attempt to turn it into a proper forward-declaration. Try:
A.h:
#pragma once
class B;
class A
{
friend class B;
private:
A();
};
You don't need the external keyword. Make it simple:
// In A.h
class B; // Forward declaration
class A
{
friend class B; // Make all the class B friend
A();
};
// In B.h
class B
{
public:
A createA() {}
};
Live Example.
Unless absolutely necessary, you should have A construct itself (or have a factory that creates A). If you really want B to do it:
class B; // foward declared
class A
{
private:
A() {}
friend class B;
};
class B
{
public:
A CreateA()
{
A a;
return a;
}
};
int main()
{
B b;
A a = b.CreateA();
return 0;
}
Note: You must forward declare B before declaring it a friend in A.
If you want just the function as a friend:
class A;
class B
{
public:
A CreateA();
};
class A
{
private:
A() {}
friend class A B::CreateA();
};
A B::CreateA()
{
A a;
return a;
}
int main()
{
B b;
A a = b.CreateA();
return 0;
}
You can make B a friend of A:
class A
{
private:
A();
friend class B;
};

Allow class access to single private member

I have a class A which has a private method called a(). I have also a class B which needs to access a() (but just B should have access to a(), thats why a() is private). I could now use a friend specifier but that would make other private methods of A (lets call them b() and c()) also available to B and I dont want that behaviour.
Is there a way to make just a() of A accessable to B?
There is a way -- if your class has a public template function:
class A {
// apparently private
void priv () { std::cout << "got you A::a()" << std::endl ; }
public:
template <class T>
void abuse() {}
};
struct Thief {};
template <>
void A::abuse<Thief>() {
this->priv();
}
int main() {
A a;
// obviously do not compile : a.priv();
// this i OK
a.abuse<Thief>();
return 0;
}
I must confess I stole this from GotW...
No there's not, but as you specify the precise class, just B could access A's private members.
You just have to take care of what method are called.
As friend relationship are not inherited, you don't have to worry about B's possible subclasses.
This could be done with some "twist".
Just factor out method a() from A class into a parent class that has B as a friend class, then let A inherit it. this will leave a() as being a method in A, but the only private method accessible by its parent's friend B.
here is a very simple code to clarify what I've said:
class parent
{
friend class B;
private:
void a() {}
};
class A:public parent
{
private:
void b() {}
void c() {}
};
class B
{
A* m_a;
public :
B()
{
m_a = new A();
m_a->a(); // OK
m_a->b(); // error C2248: 'A::b' : cannot access private member declared in class 'A'
}
};
hope it helps !
Yes, I have an easy way. Let B have a pointer of A::a(), like this:
typedef boost::function<void ()> functype;
class A {
private:
void a();
};
class B {
public:
void setfp(functype f) {m_f = f;}
void foo() {
// do some stuff
m_f();
}
private:
functype m_f;
};
A a;
B b;
b.setfp(boost::bind(&A::a, &a));
b.foo();

How to declare a friend that is a member function of another not yet defined class in C++?

How I declare B's constructor to be a friend of A? I tried:
class A
{
private:
A();
public:
friend B::B();
};
class B
{
public:
B();
};
replace B:: with class;
class A
{
private:
A();
public:
friend class B;
};
class B
{
public:
B();
};