考虑以下基类,它将计算我调用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.
}
};
注意:好的,当然这是一个简化;更普遍的问题是,当我的基类应该作为管理器运行并为跟踪类的集合执行跟踪使用模式等时,我可以强制派生类通过管理器类调用吗?或者我必须依靠派生类开发人员在这里做正确的事情吗?
答案 0 :(得分:3)
是的,你可以这样做 - 我相信这被称为传递密钥习语。
向基类添加一个“键”辅助类,只有基类可以实例化(即ctor是私有的,但是基类的朋友),但派生类可以看到。然后你将这个辅助类的引用添加到你想要“锁定”的函数的签名中,这样只有基类可以调用它 - 因为它是唯一可以实例化“key”的类。
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);
}
};
请注意,这不会像您的示例中那样阻止递归。但是你可以通过使用值而不是引用并禁用密钥的复制构造函数来实现这一点。
答案 1 :(得分:0)
如果该函数是私有的,你如何调用D类中的DerivedFunction? 这意味着你只能从B类调用CallDerivedFunction