在C ++中限制对特定类的方法访问

时间:2009-12-03 21:57:20

标签: c++ inheritance

我有两个密切相关的类,我称之为Widget和Sprocket。 Sprocket有一组方法,我希望可以从Widget调用,但不能从任何其他类调用。我也不想只是声明Widget是Spocket的朋友,因为这会让Widget访问所有受保护和私有成员。我想限制Widget只访问一组特定的方法。

我提出的一个解决方案是在Sprocket中创建一个嵌套类,它包含这些方法的包装器,并使Widget成为这个嵌套类的朋友。例如:

class Sprocket
{
public:
    class WidgetInterface
    {
        friend class Widget;
        WidgetInterface(Sprocket* parent) : mParent(parent) {}

    private:
        void A() { mParent->A(); }
        void B() { mParent->B(); }

        Sprocket* mParent;
    };

private:
    void A() { ... }
    void B() { ... }
};

class Widget
{
public:
    Widget(Sprocket* sprock) : mSprocketIface(sprock) {}

    void doStuff() { mSprocketIface.A(); }  // Widget can call Sprocket::A()

private:
    Sprocket::WidgetInterface mSprocketIface;
};

这导致一些代码重复,因为方法签名现在在两个地方声明,但它可以工作。但现在假设我想添加一个名为SpecialWidget的Widget的子类,我希望该类也可以访问Sprocket方法。我可以简单地将这个新类添加到Sprocket好友列表中,或者我可以在Widget中添加另一组受保护的包装器,SpecialWidget(和任何其他子类)可以访问但是你可以看到这现在成为一个维护问题。如果我添加新类或更改方法签名,我不想更新好友列表或包装器。如果我使用“添加另一套包装”方法,方法签名将在三个地方重复!

有人知道更简单,更清洁的方法吗?

4 个答案:

答案 0 :(得分:2)

如果你有两个紧密耦合的类,那么真的不值得尝试使friend访问更细粒度。你可以控制两者的实现,你应该相信自己,不要滥用调用一些你不需要调用的方法的能力。严格来说,需要调用。

如果你想明确未来的代码维护者,请在friend声明中添加注释,解释它为什么存在(一般来说是个好主意),以及允许哪些私有方法被调用。朋友班。

答案 1 :(得分:1)

  

Sprocket有一组方法我想从Widget调用,但不能从任何其他类调用。

为什么不为自己省点麻烦呢?在Widget中实现这组方法,可能在这些方法中添加一个Sprocket参数?

答案 2 :(得分:1)

我会将WidgetInterface实现为Sprocket继承的真实接口,因此A和B都是Widget所知道的。好吧,其他人也可以使用该界面,但他们可能有理由这样做。

答案 3 :(得分:0)

秘密是所有这些访问控制都是毫无意义和虚幻的,并且没有办法真正限制任何访问任何东西。你只是让事情复杂化,并且很难弄清楚哪些部分的小部件可以使用以及哪些部分没有。相反,使widget和sprocket的界面更加明显,并且可能让widget拥有一个私有链轮。如果人们如此无能,以至于他们会违反这一点,就没有任何帮助,但是如果你做了一些令人憎恶的事情并且很难弄明白,那么即使是那些熟悉C ++的人也无法轻易使用它。