授予对另一个类的访问权限而不暴露它

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了授予对另一个类的访问权限而不暴露它相关的知识,希望对你有一定的参考价值。

我有一个班级让我们称之为Person

class Person{
private:
    void move(x,y,z);
}

我有另一个名为PersonController的类:

class PersonController{
public:
    void control(){
        while(some_thing){
             //do some calculations
             controlled_person_->move(some_values); //Wrong Accessing to a private member
        }
    }
private:
    Person* controlled_person_;
}

PersonPersonController都是我正在设计的图书馆公共界面的一部分。

我希望PersonController能够从move打电话给Person。但是,我不希望任何人从公共接口访问此功能(move)。

解决问题的简单方法是增加友谊,以便PersonController可以访问Person的私人成员。但是,据我所知,没有引入friend关键字来解决这类问题,在这里使用它将是一个不好的做法。

  • 它是否正确?我应该在这里避免使用friend吗?
  • 这是否意味着我的设计被打破了?
  • 还有其他建议吗?
答案

从您在评论中所说的内容来看,您似乎只对PersonController触及该成员函数感兴趣。这样做的方法就是公开,但为它添加一个私钥:

class Person{
public:
    class MovePrivilege {
        move_privilege() = default; // private c'tor
        friend class PersonController; // only PersonController may construct this
    }; 

    void move(MovePrivilege, x,y,z);
};

class PersonController{
public:
    void control(){
        while(some_thing){
             //do some calculations
             controlled_person_->move(MovePrivilege{} , some_values);
        }
    }
private:
    Person* controlled_person_;
};

MovePrivilege类型有一个私人c'tor。所以它只能由它的朋友构建。它也是调用move所必需的。因此,虽然move是公开的,但唯一可以称之为MovePrivilege的朋友。

这基本上可以让您对谁可以调用移动进行细致的控制。如果这是突兀的,你不能改变移动本身,那么attorney client idiom的变体可能是合适的。

您可以随意使用。直接firend-ship只是最直接的工具。

另一答案

这正是朋友的意思。如果您的设计需要友谊,应尽量减少友谊,但没有理由不使用它。

我看到不使用朋友就像继续不喜欢'goto'一样,有时候使用它会让设计变得更清晰。

另一答案

是的,你的设计不正确。

类是数据结构的扩展概念:与数据结构一样,它们可以包含数据成员,但它们也可以包含作为成员的函数。 You can read more here

因此PersonController(如果它只控制person类)不应该是一个类,因为它不是数据结构的概念检查是否可以合并它们或设计另一种方式。

有很多方法可以做到这一点。如果你想像现在一样设计它,你可以使用受保护的访问控制器来实现你的功能和创建派生类,但它不是一个好的设计。

你也可以在这里使用友元功能,但它不是一个面向对象的概念(但最简单的方法)。

如果你想设计OO,你应该重新考虑你的设计。因为你无法在面向对象的编程中访问其他类的私有函数,它打破了封装,所以C ++不会让你这样做。

但是你的问题也取决于意见。

以上是关于授予对另一个类的访问权限而不暴露它的主要内容,如果未能解决你的问题,请参考以下文章

在 Firebase 中添加对另一个项目的访问权限

C# 授予对特定不相关类的访问权限

GitHub - 如何在共享服务器上克隆存储库而不授予我所有存储库的访问权限

Oracle 一个用户对另一个用户的完全(所有模式对象)权限

授予用户权限以仅查看 MySQL 视图而不查看其他内容

关于Android6.0权限的学习