C++: Overriding a protected method which is called by another method

▼魔方 西西 提交于 2020-06-13 19:24:58

问题


I have a very basic question concerning inheritance in C++:

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

class B : public A
{
protected:
  void print() { std::cout << "test" << std:: endl; }
};

Now the following code

B b;
b.foo();

doesn't print anything, so foo() obviously didn't call the newly defined print(). Is this only solvable by using virtual methods?


回答1:


Yes, you need to make print virtual in order for this to work. Otherwise, A::foo has no idea that descendants could provide alternative implementations of print, an happily calls A's version. Compiler may even inline the print inside foo at the time A's code is compiled, making the implementation in B completely irrelevant.




回答2:


In order for the derived class to override a function, the function must be declared virtual in the base class. That means that the function to call is chosen at run-time, when the function is called, according to the dynamic type of the object.

An alternative to overriding, if the derived type of each object is known at compile time, is to use the so-called "curiously recurring template pattern" (CRTP) to inject knowledge of the derived type into the base class (which must become a template to support this):

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; }
};



回答3:


Yes you can virtual methods to make this example work, but you can also use CRTP.




回答4:


The answer to your question, "Is this only solvable by using virtual methods?" is: no, it is possible without using virtual methods.

All you need to do is copy the foo() method over to the body of B.

class B : public A
{
public:
  void foo() { print(); }
protected:
  void print() { std::cout << "test" << std:: endl; }
};

There.




回答5:


Yes, you can't solve it without virtual methods or rewriting void foo()

because when A is compiling it doesn't know anything about B, so it can't call its method



来源:https://stackoverflow.com/questions/11592809/c-overriding-a-protected-method-which-is-called-by-another-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!