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++;
}
};
Related
i'm trying to create a costructor in the form
class A {
public:
A(void (*initializer)(A&))
{
initializer(*this);
}
};
where initializer take a reference to the instance he's passed and can make custom operation on variable it is initializing. Is there a way to make such a function friend so it can access to private variables too?
Here is a simple way:
class Impl
{
public:
int x;
int y;
};
class A
{
public:
A(void (*initializer)(Impl&))
{
initializer(_impl);
}
private:
Impl _impl;
};
This hides _impl from everyone except initializer. And since nobody other than initializer can access _impl at all, the members of of class Impl can be public, making it easy for initializer to mutate them.
Other than listing all the functions you want to pass pointers to as friends separately, no. An alternative may be to separate the data into a base class with public members you inherit privately from:
struct AData
{
int m_privateInt;
...
};
class A : private AData {
public:
A(void (*initializer)(AData&))
{
initializer(*this);
}
};
You may need to also pass a reference to A, if you want to access its member functions in initializer.
I have the following class
class A {
private:
B b;
public:
A();
}
class B {
public:
void foo();
void bar();
void foz();
........
}
B has a lot of methods. Sometimes is needed for a "customer" of class A to use method of class B. I could return a reference of B, but in this case I should return a const reference because returning a non-const reference of a private object is not good programming. If the reference is const, foo, bar and so on can't be called because they aren't const. So the only "clean" way seems to recreate the same interfaces in A using delegation to B. But this approach is not really good because I should recreate all the interfaces in A. As alternative I could set B as public in A, but it seems "strange" to me. What should I do in this case?
That is mainly an encapsulation question, and what you want to advertise in the public interface of class A.
If class B is also a public class - read can normally be used by users of class A and not a class internal to a library or framework - and if you want the existence of a B subobject to exist in the public documentation of class A and if you want to allow any operation on the B object, you can safely provide a getter.
If any of the above conditions is false, then the getter would break encapsulation and you would better define delegating methods in class A.
Depending on the general design, it could make sense to declare an interface class (say C) with only the methods that you want to allow from class A, and have B a subclass from C. Then you could safely declare a getter returning a reference on a C object:
class C {
public:
void foo(); // optionally virtual or pure virtual...
void bar();
void foz();
};
class B: public C {
.... // other members not relevant for what is public for A users
};
class A {
private:
B b;
public:
A();
C& getB() {
return b;
}
};
Solution 1. You create a getb() and return reference to B. Its not bad programming in you case particularly.
Solution 2. Create interface function for each corresponding function of b and call them.
void A::foo()
{
b.foo();
}
You can make the data member protectedinstead of private. Documentation says that protected members are not as private as private members, which are accessible only to members of the class in which they are declared, but they are not as public as public members, which are accessible in any function. protectedmembers (be they data members of method members) serve the role you're looking for : they are not accessible from everywhere (safe coding practices), but you can still manage them in clean ways when it makes sense :
If class A has an attribute of type B, is has access to B's
protected and publicmembers
friendfunctions can access both protected and publicmembers of a class they are friend with.
When preceding the name of a base class, the protected keyword specifies that the public and protected members of the base class are protected members of its derived classes.
Here, you're interested by the first item of the list : you can access B' methods from A; BUT B has still safeguards.
When I run the following code (adapted from your code) :
#include <iostream>
using std::cout;
using std::endl;
class B {
public:
void foo() { cout << "foo" << endl; };
void bar() { cout << "bar" << endl; };
void foz() { cout << "foz" << endl; };
};
class A {
protected: // <===== THIS IS THE SIGNIFICANT BIT
B b;
public:
A() {
b.foo();
b.bar();
b.foz();
cout << "A constructor" << endl;
};
};
int main(int argc, char** argv) {
A myA;
return 0;
}
I get the following console output :
foo
bar
foz
A constructor
Which shows that I can access B's methods from A.
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();
...
I'm new to c++ and I need to read from private class members of a class in a method that's in a different class, for example:
class a{
private:
int x;
}
class b{
void foo();
}
void b::foo(){
//here I want to read from x that's in a
}
Do I have to set up a function in class a like int readx(){return x);) or a readclass(){return *this);}? Is there another way?
The private section of a class has the objective of 'hiding' the way you handle the data, providing a streamlined way of accesing said data with public methods.
The advantage of using a public method to change the value of private members is that you can, for example, allow values only between 0 and 10 for 'x'.
In your case, you should think about what does 'x' represent in your first class, and if it makes sense for the second class to access it directly and without any control or special consideration. If this is the case, it should probably be a public value. In the other case, you will need to make a public method to read it, like your readx example.
If only 'b' has the privilege to access 'x' directly, you can also define a friend function, like someone already said.
Note that returnig a pointer to the instance wouldn't allow access to private members of the class.
You could use friend class or function, but it is a bad idea to use private members of methods (tests are only reasonable excuse for that). Better to use public methods for that or redesign your code if you couldn't avoid usage of private members.
You can implement a friend function that can access x in foo.
Reference
If there is no accessor to this data member in class a then you should declare the member function of class b as a friend function of class a.
For example
#include <iostream>
class B
{
public:
void foo() const;
};
class A
{
public:
A( int x ) : x( x ){}
private:
friend void B::foo() const;
int x;
};
void B::foo() const
{
A a { 10 };
std::cout << a.x << std::endl;
}
int main()
{
B().foo();
return 0;
}
Declaring a friend function or class would grant read and write access to a's x to that function or class, a
class a {
public:
const int& readx() const { return x; }
private:
int x
};
or, if you like that semantics better
class a {
public:
const int& x() const { return x_; }
private:
int x_;
};
grants read access only, but to every client.
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;*