C++:覆盖由另一个方法调用的受保护方法

ph4*_*t0m 8 c++ inheritance

我有一个关于C++继承的非常基本的问题:

class A
{
public:
  void foo() { print(); }
protected:
  void print() {}
};

class B : public A
{
protected:
  void print() { std::cout << "test" << std:: endl; }
};
Run Code Online (Sandbox Code Playgroud)

现在以下代码

B b;
b.foo();
Run Code Online (Sandbox Code Playgroud)

不打印任何东西,所以foo()显然没有调用新定义的print().这只能通过虚拟方法解决吗?

das*_*ght 9

是的,你需要print虚拟以使其工作.否则,A::foo不知道后代可以提供print一个愉快的调用A版本的替代实现.编译器甚至可以在编译代码时内联print内部,使得实现完全无关紧要.fooAB


Mik*_*our 5

为了使派生类重写函数,必须virtual在基类中声明该函数。这意味着要调用的函数是在运行时根据对象的动态类型选择的。

如果在编译时知道每个对象的派生类型,则覆盖的替代方法是使用所谓的“好奇重复模板模式”(CRTP)将派生类型的知识注入基类(必须成为基类)。支持此的模板):

template <typename Derived> class A
{
public:
  void foo() { static_cast<Derived*>(this)->print(); }
};

class B : public A<B>
{
private:
  friend class A<B>; // assuming you don't want to make the function public
  void print() { std::cout << "test" << std:: endl; }
};
Run Code Online (Sandbox Code Playgroud)