受保护功能不需要虚拟

时间:2011-09-12 10:29:41

标签: c++ inheritance virtual

说类B派生自班级A。这两个都声明f()。 f受到保护。因此f只会在A内和B内调用。 f()是否需要声明为虚拟?

或者更确切地说:C来自B派生自ABA声明受保护的非虚拟f()。将来自f()C的{​​{1}}来电解析为B而A中的来电是B::f()吗?

在这种情况下,我们是否应该始终避免虚拟受保护成员具有静态解析?这是自动完成的吗?谢谢!

4 个答案:

答案 0 :(得分:2)

只要在f()派生的函数中完成对A的调用(并且未在BC中重载/重新实现),{{1指针解析为this,因此调用A*。所以不,在这种情况下你还需要一个虚函数。

答案 1 :(得分:1)

当您需要多态行为时,需要声明受保护的方法virtual(例如Template Method pattern),并且在您不需要时应该避免。但是,在后一种情况下,你不应该在子类中使用具有相同签名的另一个函数来遮蔽函数,否则你会遇到令人费解的行为(就像你在第2段中描述的那样),这可能会产生微妙的错误。

答案 2 :(得分:0)

我的C ++上有点生疏,但我会说只有在声明方法private时才能保证“静态分辨率”,因此你需要virtualprotected一起使用在您的方案中......

答案 3 :(得分:0)

所以:

class A {
public:
  void f() { std::cout << "A::f\n"; }
};

class B : public A {
public:
  void f() { std::cout << "B::f\n"; }
};

只要编译器知道对象实际上是B,它就会在B中调用f()。但是,情况并非总是这样:

void callF(A* a)
{
  a->f();
}

B b;
callF(&b);  // prints A::f

如果您希望callF等函数调用正确的f()函数,请将其设为virtual。通常,如果在后代类中覆盖它们是有意义的,则将函数设置为虚拟。这通常是受保护功能的情况。