So i have problem trying to access a friend class properties, i need a pointer to the first item in the map.
class.h
class A{
private:
map<int,float> database;
public:
......
class B{
private:
map<int,float>::iterator it;
public:
friend class A;
B begin();
}
}
and implem.hxx
A::B A::B::begin(){
A::B it;
ite.it = database.begin();
return ite;
}
But it shows a problem when compiling:
error: invalid use of non-static data member A::database
How can i resolve the problem?
Besides some syntax issues, I see the A::database variable is attempted to be accessed in A::B::begin(). But this variable is not static to access it in that way, and class B is not derived from A as well. So, that the question imho has nothing to do with the friendship.
First thing to note is that it is completely redundant to make A a friend of B. Inner classes in C++ have access to private members of outer classes. However, when you're creating an instance of B, in there is no instance of class A, for which you are trying to access the map. You need an instance.
A::B doesn't have an enclosing creating instance of A like in Java for example - begin needs an object of type A to access its database:
A::B A::B::begin(A& a) {
A::B b;
b.it = a.database.begin();
return b;
}
Note that A::B doesn't need to declare A as friend to access private members of A (friend works the other way around) B already has access to the private members since it is nested.
It seems to me you wanted to wrap iterators of A::database in B, so hopefully this points you in the right direction:
class A {
std::map<int,float> database;
public:
class B {
friend class A;
std::map<int,float>::iterator it;
explicit B(std::map<int,float>::iterator it) : it(it) { }
...
};
B begin();
};
A::B A::begin() {
return B(database.begin());
}
Now begin is a member function of A and creates a B using a private constructor only A may access. Here's the usage code:
A a;
A::B b = a.begin();
...
Related
The following code compiles on MSVC:
#include <iostream>
class Bob
{
int a;
friend class Outer;
};
class Outer
{
class Inner
{
void f(Bob obj)
{
std::cout << obj.a; //OK
}
};
};
So it seems that if Outer is a friend of Bob, so is Inner, automatically. I am reading the Friends chapter of the standard and am unable to find a clause that would confirm or refute this.
Is this legal, and if so, what's the chapter and verse?
[class.access.nest]/1 states that
A nested class is a member and as such has the same access rights as any other member
So I believe yes, this is standard behavior.
Let's say that Outer has a member function foo(). That function, of course, will have access to Bob's members. To my understanding, the part that I quoted implies that any nested class inside Outer would have the same access rights as foo(), thus having the ability to access Bob's members.
It is also worth noting that the standard contains the following example ([class.friend]/2), note the usage of A::B in Y:
class A {
class B { };
friend class X;
};
struct X : A::B {
// OK: A::B accessible to friend
A::B mx; // OK: A::B accessible to member of friend
class Y {
A::B my; // OK: A::B accessible to nested member of friend
};
};
Hello I am wondering why C++ standard allows us in nested classes to access outer class's private fields, while it forbids to access inner class's private fields from the outer class. I understand, that this example:
class OuterClass{
public:
class InnerClass{
public:
void printOuterClass(OuterClass& outer) {cout << outer.m_dataToDisplay;};
};
private:
int m_dataToDisplay;
};
is fine, because thing, that Inner class sometimes can be complicated. But I think following scenario is also fine:
class Algorithm{
public:
class AlgorithmResults{
public:
void readAlgorithmResult();
private:
void writeAlgorithmResult();
};
void calculate(AlgorithmResults& results, Arguments...){
//calculate stuff
results.writeAlgorithmResult(results);
}
};
For me this structure makes perfect sense, although it is not allowed in C++. I also noticed, that for some time both were allowed in Java, but now second example is also forbidden.
What is the reason, that first example is allowed and another is denied?
Essentially, within a scope names declared earlier in that scope are valid and can be used directly (unless they're shadowed). Code outside a scope can't directly use names declared inside the scope. E.g. code after a curly braces block, can't directly use variables declared inside that block (an example of indirect use is when the outside code has access to a pointer to a static variable inside the curly braces block).
For the second example, just make Algorithm a friend of AlgorithmResults:
class AlgorithmResults
{
friend class Algorithm;
The nested classes could access outer class's private fields, because it's a member of the outer class, just same as the other members.
[class.access.nest]/1
A nested class is a member and as such has the same access rights as any other member.
On the other hand, the outer class doesn't have special access rights on the nested class, they're just normal relationship.
The members of an enclosing class have no special access to members of a nested class; the usual access rules ([class.access]) shall be obeyed. [ Example:
class E {
int x;
class B { };
class I {
B b; // OK: E::I can access E::B
int y;
void f(E* p, int i) {
p->x = i; // OK: E::I can access E::x
}
};
int g(I* p) {
return p->y; // error: I::y is private
}
};
— end example ]
Counter question: Why would you want to allow it?
If you need an outer class have access to an inner class' private internals, you can befriend:
class Foo {
public:
class Frob {
friend class Foo;
int privateDataMember;
};
Foo () {
Frob frob;
frob.privateDataMember = 3735928559;
}
};
C++ has no device to unfriend, so allowing default private access to an outer class would steal you a class design tool and yield reduced default encapsulation.
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++;
}
};
I wanted to pass-in functions as arguments to a templated function without having any indirection. To achieve this I created two nested structs, each defining the function I wish to pass in to the templated function. Each of the structs accesses data members from the outside class B:
namespace A{
class B{
public:
B();
template <typename T>
void templatedFunction(T t){
//I pass one of the struct objects in to here, to invoke the desired function
t();
}
private:
struct X{
void operator(){
do();
}
void do(){
//Accesses the data members of class B
e->doSomething();
}
};
struct Y{
void operator(){
do();
}
void do(){
//Accesses the data members of class B
d.doSomething();
}
};
C* c;
D d;
E* e;
};
}
and the compiler errors I get are pretty much all of the format:
error: invalid use of non-static data member B::d
for the lines within the struct accessing the class data members and on the lines declaring the data members in B.
A nested class in C++ does not (automatically) have access to an instance of the containing class. It's just a class definition like any other. You need a B instance to access non-static data members of B.
You can restructure your nested class Y as
struct Y
{
void operator()( B& b ){
do( b );
}
void do( B& b ){
//Accesses the data members of class B
b.d.doSomething();
}
};
and fix your function template and calls, and class X, accordingly.
Note that your presented code for operator(), with no argument list, would not have compiled, but I'm not downvoting since you are stopped by another compilation error (i.e., possibly it is the real code you're showing).
If you have a struct (or class for that matter) nested in another class, it it not treated specially in any way. It works exactly the same as if the struct was defined outside of the enclosing class. The only thing which is different is the scope of nested class name. So, if you have
class A { class B{}; };
and
class B{}; class A {};
the only difference is that outside class A you need to name the class B as A::B in the first case, and just B in the second class. There is no other difference, and in particular class B does not gain any special access to class A members.
For a code like this:
class foo {
protected:
int a;
public:
class bar {
public:
int getA() {return a;} // ERROR
};
foo()
: a (p->param)
};
I get this error:
invalid use of non-static data member 'foo::a'
currently the variable a is initialized in the constructor of foo.
if I make it static, then it says:
error: 'int foo::a' is a static data member; it can only be initialized at its definition
However I want to pass a value to a in the constructor.
What is the solution then?
In C++, unlike (say) Java, an instance of a nested class doesn't intrinsically belong to any instance of the enclosing class. So bar::getA doesn't have any specific instance of foo whose a it can be returning. I'm guessing that what you want is something like:
class bar {
private:
foo * const owner;
public:
bar(foo & owner) : owner(&owner) { }
int getA() {return owner->a;}
};
But even for this you may have to make some changes, because in versions of C++ before C++11, unlike (again, say) Java, a nested class has no special access to its enclosing class, so it can't see the protected member a. This will depend on your compiler version. (Hat-tip to Ken Wayne VanderLinde for pointing out that C++11 has changed this.)
In C++, nested classes are not connected to any instance of the outer class. If you want bar to access non-static members of foo, then bar needs to have access to an instance of foo. Maybe something like:
class bar {
public:
int getA(foo & f ) {return foo.a;}
};
Or maybe
class bar {
private:
foo & f;
public:
bar(foo & g)
: f(g)
{
}
int getA() { return f.a; }
};
In any case, you need to explicitly make sure you have access to an instance of foo.
The nested class doesn't know about the outer class, and protected doesn't help. You'll have to pass some actual reference to objects of the nested class type. You could store a foo*, but perhaps a reference to the integer is enough:
class Outer
{
int n;
public:
class Inner
{
int & a;
public:
Inner(int & b) : a(b) { }
int & get() { return a; }
};
// ... for example:
Inner inn;
Outer() : inn(n) { }
};
Now you can instantiate inner classes like Inner i(n); and call i.get().
You try to access private member of one class from another. The fact that bar-class is declared within foo-class means that bar in visible only inside foo class, but that is still other class.
And what is p->param?
Actually, it isn't clear what do you want to do
Your Question is not clear but there is use case when you will get this issue .
Invalid use of non-static data member.
When you are using "non-static data member in another class try to not use with scope resolution operator
Example::className::memberData = assignivalue ;
instead of above try to use object of className class;
Example:: m_pClassName->memberData=assignValue;*