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

时间:2017-12-17 20:38:17

标签: c++ design-patterns

我有一个课程,我们称之为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吗?
  • 这是否意味着我的设计被打破了?
  • 任何其他建议?

3 个答案:

答案 0 :(得分:5)

根据您在评论中所说的内容,您似乎只对允许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; tor。所以它只能由它的朋友构建。调用move也需要它。因此,move是公开的,唯一可以称之为MovePrivilege的朋友。

这基本上可以让你对谁可以调用move进行细致的控制。如果这是突兀的,并且您无法自行更改移动,则attorney client idiom的变体可能适合。

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:-1)

是的,你的设计不正确。

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

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

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

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

你应该重新考虑你的设计如果你想设计它OO 。因为你不能从面向对象编程中的其他类访问私有函数,它打破了封装,所以C ++赢了&#39你能做到这一点。

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