仅由另一个类访问的类

时间:2017-08-30 18:22:12

标签: c++

我有一个声明一些静态变量的类:

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

现在A类可以被任何人/任何地方访问,并且可以操纵其成员变量。如何只允许另一个可以访问A类静态变量/方法的类?

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

4 个答案:

答案 0 :(得分:4)

A内的B定义为私有类。

#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();
}

答案 1 :(得分:3)

如果该类在另一个类中被识别,那么我会说它应该是该类的私有实现细节

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

现在除了A之外,任何人都不知道B的存在。

答案 2 :(得分:2)

CRTP让您无需触摸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;
};

现在B可以访问private的{​​{1}}内容,A_shared_with_B可以访问A_shared_with_B private内容,{ {1}}无法直接访问A的{​​{1}}内容。

如果您愿意修改B并重命名private,则在A的{​​{1}}部分中命名B会使名称难以从外部覆盖A,与上述访问控制类似。这种技术的一个很好的优点是,您可以通过将一个无用的A实例传递给外部private函数来授予B代理访问权限:

B

A的实例可以调用A并授予将template用于给定(模板)函数的权限。

答案 3 :(得分:0)

已经有答案显示如何使A成为内部类。为了完整起见,这里是private + friend解决方案(已在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;}
};

friend可以访问某个班级的所有成员,因此您可以将A的所有成员设为私有,并仅通过将其设为好友来授予B访问权限。