Reputation: 8687
I have a class which declares some static variables:
#include <iostream>
class A
{
private:
static int x;
public:
static int y;
static getX(){ return A::x;}
static setX(int z){ A::x = z;}
};
int A::x = 0;
int A::y = 0;
Now class A can be accessed by anyone/anywhere and its member variables can be manipulate. How can I allow only one another class that will have access to class A static variables / methods?
class B
{
public:
void showX(){A::setX(9) ; std::cout << A::getX() << std::endl;}
void showY(){A::y = 8; std::cout << A::y << std::endl;}
};
int main()
{
B b1;
b1.showX();
b1.showY();
}
Upvotes: 2
Views: 67
Reputation: 2734
Define A
inside B
as private class.
#include <iostream>
class B
{
class A
{
private:
static int x;
public:
static int y;
static int getX() {
return A::x;
}
static void setX(int z) {
A::x = z;
}
};
public:
void showX() {
A::setX(9) ;
std::cout << A::getX() << std::endl;
}
void showY() {
A::y = 8;
std::cout << A::y << std::endl;
}
};
int B::A::x = 0;
int B::A::y = 0;
int main()
{
B b1;
b1.showX();
b1.showY();
}
Upvotes: 4
Reputation: 275230
CRTP lets you do this without touching B:
class B;
template<class A>
class A_shared_with_B {
private:
static int y;
static int getX(){ return A::x;}
static void setX(int z){ A::x = z;}
friend class B;
};
class A:public A_shared_with_B<A> {
friend class A_shared_with_B<A>;
private:
static int x;
};
now B
has access to the private
contents of A_shared_with_B
, A_shared_with_B
has access to the private
contents of A
, and B
does not have direct access to the private
contents of A
.
If you are willing to modify B
and rename A
, naming A
within the private
section of B
makes the name difficult to reach from outside B
, which is similar to the above access control. A nice advantage to this technique is that you can grant proxy access to A
by passing an otherwise useless instance of A
to an external template
function:
template<class A>
void has_proxy_A_access( A ) {
std::cout << A::getX();
}
where instances of B
can call has_proxy_A_access( A{} )
and grant rights to use A
to a given (template) function.
Upvotes: 2
Reputation: 122133
There are already answer showing how to make A
an inner class. For the sake of completeness here is the private
+friend
solution (already proposed in a comment by Neil Butterworth):
#include <iostream>
class A {
private:
friend class B;
static int x;
static int y;
static getX(){ return A::x;}
static setX(int z){ A::x = z;}
};
A friend
has access to all members of a class, so you can make all members of A
private and grant only B
access to them by making it a friend.
Upvotes: 0
Reputation: 117856
If the class should only be known in one other class, then I would say it should be a private implementation detail of that class
class B
{
private:
class A
{
private:
static int x;
public:
static int y;
static int getX(){ return A::x;}
static void setX(int z){ A::x = z;}
};
public:
void showX(){A::setX(9) ; std::cout << A::getX() << std::endl;}
void showY(){A::y = 8; std::cout << A::y << std::endl;}
};
int B::A::x = 0;
int B::A::y = 0;
int main()
{
B b1;
b1.showX();
b1.showY();
}
Now the existence of A
isn't known by anyone except B
.
Upvotes: 3