[英]Restricting access to derived class for a pure virtual function in c++
class A
{
public:
void virtual magic() = 0;
void bar()
{
magic(); // this should be legal
}
};
class B: public A
{
public:
void magic()
{
cout<<"implement magic here"<<endl;
}
};
class C: public B
{
void foo()
{
magic(); // this should not be allowed, i.e. create compile-time error
}
};
因此, B
的纯虚基类A
应该可以访问magic()
,但不能访问任何B
派生类C
这可以使用访问说明符和/或朋友声明或以任何其他方式实现吗?
基本上,您无法降低虚拟方法的可见性。 一旦它在A
公开,就没有任何整洁的方法可以使它在任何派生类中受到保护或私有。
如果您有权访问class A
,请将magic
访问权限更改为private
:
private:
void virtual magic() = 0;
然后让B班成为A班的朋友:
class A
{
friend class B;
您真正想要的是使用所谓的模板方法模式,最有可能将公共接口与继承的实现细节分开 。
您的公共接口应使用非虚方法。 虚拟方法应该都是私有的。 然后基类中的接口可以强制执行不变量并进行样板工作。 派生类仍然可以覆盖虚方法 ,它们不能直接调用它。
仅当派生类需要调用虚方法的基本实现时,才能使虚方法受到保护。 这几乎都是。
基类析构函数应该是公共的和虚拟的,或者是受保护的和非虚拟的。 前者当您希望使用基类接口执行销毁时。 现在 ,这真的全部:)
具体来说:
#include <iostream>
#include <cassert>
using namespace std;
class A
{
// we do magic without sprinking any dust, but optionally we could sprinkle some beforehand
void virtual sprinkle() {};
void virtual magic(int) = 0;
public:
void doSomeMagic(int power) {
assert(power > 3 and power < 8);
sprinkle();
magic(power);
}
virtual ~A() {}
};
class B: public A
{
void magic(int power) {
cout << "B: did magic of with power=" << power << endl;
}
};
class C : public B
{
void sprinkle() {
cout << "C: also sprinked some dust before doing the magic" << endl;
}
};
int main()
{
B b;
C c;
b.doSomeMagic(5);
c.doSomeMagic(6);
return 0;
}
B: did magic of with power=5
C: also sprinked some dust before doing the magic
B: did magic of with power=6
正如Dave S的评论所示,更改C :: magic()的访问说明符:
class A
{
public:
void virtual magic() = 0;
};
class B: public A
{
public:
void magic()
{
cout<<"implement magic here"<<endl;
}
};
class C:public B
{
private:
void virtual magic(){};
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.