Acces private static member variable in namespace from another class C++ - 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.

Related

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.

Use friend class in gcc

I have this class that compiles in VC14, but when I try to compile in gcc 4.8.5, it doesn't work, I get "error: C was not declared in this scope".
class A
{
};
class B : public A
{
friend class C;
friend class D;
private:
class BB
{
std::list<C> c;
std::list<D> d;
};
};
class C : public B::BB
{
};
class D : public B::BB
{
};
I tried to forward declare "class C" before the definition of class B, but it gives me an error because it doesn't have the same definition as "class C : public B::BB", and I can't put that definition because BB is private... I'm not sure what to do.
Thanks
Forward declarations that use friend are different from other forward declarations. Writing friend class C; within the definition of B declares that there is a class called C in the enclosing namespace (i.e., the global namespace) but does not actually introduce the name C into that scope. Therefore, you can't write something like List<C> because the name C cannot be found. You should do this:
class C;
class D;
class B : public A
{
friend class C;
friend class D;
private:
class BB
{
List<C> c;
List<D> d;
}
}
The namespace-scope declarations actually introduce the names C and D into the global scope. Then, the friend declarations make those classes friends of B.
At the time you do
List<C> c;
List<D> d;
the compiler has no idea what C and D are--you haven't declared/implemented them yet!
You don't have to completely implement them, but you'll need to at least tell the compiler they're class that'll be implemented at some point. You can do that with:
class C;
class D;
Full working example (with some minor fixes like adding semicolons to make it compile): ideone

Friendship in nested classes C++

I am trying to understand concept of friendship in nested classes but I am not getting the concept properly. I have written a sample program to understand it but the program is not working
#include<iostream>
using namespace std;
class outerClass
{
private:
int a;
public:
class innerClass;
bool print(innerClass);
};
class innerClass
{
friend class outerClass;
private:
int b;
public:
innerClass() =default;
};
bool outerClass::print(outerClass::innerClass obj)
{
cout<<"Value of b in inner class is:"<<obj.b;
}
int main()
{
outerClass in;
outerClass::innerClass obj;
obj.b=5;
in.print(obj);
}
I am getting below errors:
try.cpp: In member function ‘bool outerClass::print(outerClass::innerClass)’:
try.cpp:26:6: error: ‘obj’ has incomplete type
try.cpp:11:15: error: forward declaration of ‘class outerClass::innerClass’
try.cpp: In function ‘int main()’:
try.cpp:34:28: error: aggregate ‘outerClass::innerClass obj’ has incomplete type and cannot be defined
As I read through articles on internet I learnt following points please comment on them if they are correct or not:
innerClass can access all the members of outerClass by default.
For outerClass to access private members of innnerClass we need to make outerClass as friend class to innerClass.
Please help in pointing out the mistake in code and also if the points I understood are correct.
The line class innerClass; within outerClass is a forward declaration to a class that you never define.
Hence outerClass::innerClass is an incomplete type.
The separate innerClass definition that starts with
class innerClass
{
is a completely different class to the forward declared class.
There's nothing wrong with your friend class outerClass; statement within the defined innerClass.
If you want to define innerClass outside of outerClass, here is how to do it:
class outerClass
{
class innerClass; // forward declaration
};
class outerClass::innerClass // definition
{
};
The rest is OK, except of obj.b=5. The class outerClass is allowed to access innerClass::b, the function main() is not.
innerClass can access all the members of outerClass by default.
Right. From the standard [class.access.nest]:
A nested class is a member and as such has the same access rights as any other member.
For outerClass to access private members of innnerClass we need to make outerClass as friend class to innerClass.
Right. From the standard [class.access.nest]:
The members of an enclosing class have no special access to members of a nested class;
I think you are confusing with nested class and friend class
You can use friend class not using nested class and
you can use nested class not using friend class
Here are some example:
class A {};
class B {};
Here the A class knows the B class, but the B cannot know the A class. So you need to tell the A class that the B class is exist.
This doing thing, is called Forward Declaration
So:
class B; // forward declaration
class A {}; // A knows the B
class B {}; // B knows the A

How can you access nested classes

If I have something along the following lines
namespace mynamespace
{
class A
{
public:
class B{};
class C{};
};
int foo(B bObject, C cObject); //error
}
When compiled, B and C do not name types. Is there a way so that I can define functions in the namespace that use public nested classes (B and C) defined in Class A?
Use the scope resolution operator. B and C are declared in the scope of class A.
int foo(A::B bObject, A::C cObject);

C++: granting member function friendship forward declaration?

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;
}