0

考虑以下基类,它将计算我调用 CallDerivedFunction 的次数:

class B {
  public:
    B() {numCalls = 0;}
    void CallDerivedFunction() {numCalls++; DerivedFunction();}
    int GetNumCalls() {return numCalls;}
  private:
    virtual void DerivedFunction() = 0;
    int numCalls;
};

除了我之外,其他人将编写实现 DerivedFunction 的派生类。但是,我试图计算调用 DerivedFunction 的次数。

有什么方法可以防止派生类 D 直接调用它自己的 DerivedFunction 实现,例如。不允许:

class D : public B {
  private:
    void DerivedFunction() {
      if(<some condition>) DerivedFunction(); // I don't want to allow this.
      if(<some condition>) CallDerivedFunction(); // This is OK.
    }
};

注意:好的,当然这是一个简化;更普遍的问题是,当我的基类应该充当管理器并为派生类的集合执行跟踪使用模式等操作时,我可以强制派生类通过管理器类调用吗?还是我必须依靠派生类开发人员来做正确的事情?

4

2 回答 2

4

是的,你可以这样做——我相信这被称为密码习语。

您向您的基类添加一个“关键”帮助类,只有基类可以实例化(即ctor 是私有的,但基类的朋友),但派生类可以看到。然后,您将对该辅助类的引用添加到您希望“锁定”的函数的签名中,以便只有基类可以调用它——因为它是唯一可以实例化“键”的类。

class A
{
   public:
     class Key {Key(); friend ::A;};
     // Only A can call this, since only A can instantiate A::Key
     virtual void Foo(A::Key&)=0; 
};


class B:public A
{
  public:
    virtual void Foo(A::Key&) override
    {
      // B can override this...
    }

    void Bar()
    {
      Key k; // <- this wont compile, so you cannot call Foo from B
      this->Foo(k);
    }
};

请注意,这不会像您的示例中那样阻止递归。但是您可能可以通过使用值而不是引用并禁用键的复制构造函数来使其工作。

于 2012-06-20T22:16:15.270 回答
0

如果该函数是 Private ,您将如何在 D 类中调用 DerivedFunction ?这意味着您只能从 B 类调用 CallDerivedFunction

于 2012-06-20T20:21:47.633 回答