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

问题描述 投票:0回答:3

我有一个班级让我们称之为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吗?
  • 这是否意味着我的设计被打破了?
  • 还有其他建议吗?
c++ design-patterns
3个回答
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。所以它只能由它的朋友构建。它也是调用move所必需的。因此,虽然move是公开的,但唯一可以称之为MovePrivilege的朋友。

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

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


1
投票

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

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


-1
投票

是的,你的设计不正确。

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

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

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.