受保护的函数不需要虚拟



B类衍生自A类。它们都声明为f()。F受到保护。因此,f将只在AB内部调用。f()需要被声明为虚拟吗?

或者说:CB衍生自ABA声明受保护的非虚拟f()。在CB中对f()的调用会解析为B::f(),在a中解析为A::f()吗?

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

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

声明你的保护方法virtual是必要的,当你想要多态行为(一个例子是模板方法模式),是避免当你不这样做。然而,在后一种情况下,你不应该用子类中具有相同签名的另一个函数来掩盖函数,否则你会得到令人困惑的行为(就像你在第二段中描述的那样),这可能会导致微妙的bug。

我对我的c++有点生锈了,但我想说的是,"静态分辨率"只有在你声明private方法时才能得到保证,因此你需要virtualprotected在你的场景中…

So:

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

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

void callF(A* a)
{
  a->f();
}
B b;
callF(&b);  // prints A::f

如果你想让callF这样的函数调用正确的f()函数,把它改成virtual。通常,如果在子类中重写函数是有意义的,则将其设置为虚函数。

最新更新