Programmer
Programmer

Reputation: 8687

A Class to be accessed by another class only

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

Answers (4)

Artemy Vysotsky
Artemy Vysotsky

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

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

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

463035818_is_not_an_ai
463035818_is_not_an_ai

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

Cory Kramer
Cory Kramer

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

Related Questions