• <i id='Uhyh2'><tr id='Uhyh2'><dt id='Uhyh2'><q id='Uhyh2'><span id='Uhyh2'><b id='Uhyh2'><form id='Uhyh2'><ins id='Uhyh2'></ins><ul id='Uhyh2'></ul><sub id='Uhyh2'></sub></form><legend id='Uhyh2'></legend><bdo id='Uhyh2'><pre id='Uhyh2'><center id='Uhyh2'></center></pre></bdo></b><th id='Uhyh2'></th></span></q></dt></tr></i><div id='Uhyh2'><tfoot id='Uhyh2'></tfoot><dl id='Uhyh2'><fieldset id='Uhyh2'></fieldset></dl></div>
      • <bdo id='Uhyh2'></bdo><ul id='Uhyh2'></ul>

      <small id='Uhyh2'></small><noframes id='Uhyh2'>

        <tfoot id='Uhyh2'></tfoot>

        <legend id='Uhyh2'><style id='Uhyh2'><dir id='Uhyh2'><q id='Uhyh2'></q></dir></style></legend>

        如何强制子虚拟函数首先调用其父虚拟函数

        How to force child same virtual function call its parent virtual function first(如何强制子虚拟函数首先调用其父虚拟函数)
          <bdo id='9QWip'></bdo><ul id='9QWip'></ul>
            <tfoot id='9QWip'></tfoot>
          • <small id='9QWip'></small><noframes id='9QWip'>

              <tbody id='9QWip'></tbody>
            1. <legend id='9QWip'><style id='9QWip'><dir id='9QWip'><q id='9QWip'></q></dir></style></legend>
              <i id='9QWip'><tr id='9QWip'><dt id='9QWip'><q id='9QWip'><span id='9QWip'><b id='9QWip'><form id='9QWip'><ins id='9QWip'></ins><ul id='9QWip'></ul><sub id='9QWip'></sub></form><legend id='9QWip'></legend><bdo id='9QWip'><pre id='9QWip'><center id='9QWip'></center></pre></bdo></b><th id='9QWip'></th></span></q></dt></tr></i><div id='9QWip'><tfoot id='9QWip'></tfoot><dl id='9QWip'><fieldset id='9QWip'></fieldset></dl></div>

                  本文介绍了如何强制子虚拟函数首先调用其父虚拟函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  伙计们,我有一个案例,需要子类需要先调用其父虚函数,然后再调用其覆盖虚函数.

                  guys, I have a case that needs the child class needs to call its parent virtual function at first before call its override virtual function.

                  BaseClass::Draw()
                  {
                  
                  }
                  
                  ChildClass::Draw()
                  {
                      BaseClass::Draw(); // BaseClass Draw must be called first.
                  }
                  
                  GrandChildClass::Draw()
                  {
                      ChildClass::Draw(); // ChildClass Draw must be called first.
                  }
                  

                  我想对客户隐藏这种行为.这个有图案吗?

                  I want to hide this behavior from clients. Is there pattern on this?

                  谢谢.

                  推荐答案

                  对于简单的情况,您可以使用第二个私有成员函数来实现可重写行为:

                  For simple cases you can use a second, private member function for the overrideable behavior:

                  class Base {
                  public:
                      void Draw() { 
                          // Base-class functionality here
                          OverrideableDraw();
                      }
                  
                  private:
                      virtual void OverrideableDraw() { }
                  };
                  
                  class Derived : public Base {
                  private:
                      virtual void OverrideableDraw() {
                          // Derived-class functionality here
                      }
                  };
                  

                  <小时>

                  对于更复杂的层次结构(例如,您有多个继承级别),这是不可能的,因为任何派生类都可以覆盖任何虚拟成员函数(C++ 中没有 final).通常可以安全地假设每个派生类都在做正确的事情.虽然我可以想到有几次我因为派生类搞砸了覆盖而遇到问题,但这些情况通常很容易调试.


                  For more complex hierarchies (e.g. where you have multiple levels of inheritance), this isn't possible since any derived class can override any virtual member function (there is no final in C++). Usually it is safe to assume that each derived class is doing the right thing. While I can think of a few times that I've run into issues because a derived class screwed up overriding, those cases were usually pretty straightforward to debug.

                  如果您真的很担心并且真的想保证首先执行基类覆盖,您可以使用类似这样的方法,尽管这非常昂贵(至少这种幼稚的实现非常昂贵):

                  If you are really worried about it and really want to guarantee that base-class overrides are executed first, you could use something like this, though this is quite expensive (at least this naive implementation is quite expensive):

                  #include <functional>
                  #include <iostream>
                  #include <vector>
                  
                  class Base {
                  public:
                  
                      Base() {
                          RegisterDrawCallback(std::bind(&Base::DrawCallback, this));
                      }
                  
                      void Draw() {
                          for (auto it(drawCallbacks_.begin()); it != drawCallbacks_.end(); ++it)
                              (*it)();
                      }
                  
                  protected:
                  
                      typedef std::function<void(void)> DrawCallbackType;
                      typedef std::vector<DrawCallbackType> DrawSequence;
                  
                      void RegisterDrawCallback(DrawCallbackType f) {
                          drawCallbacks_.push_back(f);
                      }
                  
                  private:
                  
                      void DrawCallback() { std::cout << "Base" << std::endl; }
                  
                      DrawSequence drawCallbacks_;
                  };
                  
                  class Derived : public Base {
                  public:
                  
                      Derived() {
                          RegisterDrawCallback(std::bind(&Derived::DrawCallback, this));
                      }
                  
                  private:
                  
                      void DrawCallback() { std::cout << "Derived" << std::endl; }
                  };
                  
                  class DerivedDerived : public Derived {
                  public:
                  
                      DerivedDerived() {
                          RegisterDrawCallback(std::bind(&DerivedDerived::DrawCallback, this));
                      }
                  
                  private:
                  
                      void DrawCallback() { std::cout << "DerivedDerived" << std::endl; }
                  };
                  

                  [这只是一种选择;其他人可能会想出一个更优雅的解决方案.就我个人而言,我只是要确保虚拟成员函数的文档齐全,然后就可以了.]

                  [This is just one option; someone else can probably come up with a far more elegant solution. Personally, I'd just make sure the virtual member functions are well-documented and leave it at that.]

                  这篇关于如何强制子虚拟函数首先调用其父虚拟函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

                  相关文档推荐

                  Consistent pseudo-random numbers across platforms(跨平台一致的伪随机数)
                  Vary range of uniform_int_distribution(改变uniform_int_distribution的范围)
                  What is a seed in terms of generating a random number?(就生成随机数而言,种子是什么?)
                  Is 1.0 a valid output from std::generate_canonical?(1.0 是 std::generate_canonical 的有效输出吗?)
                  Getting big random numbers in C/C++(在 C/C++ 中获取大随机数)
                  What is the best way to generate random numbers in C++?(在 C++ 中生成随机数的最佳方法是什么?)
                        <tbody id='Anzwy'></tbody>

                      <legend id='Anzwy'><style id='Anzwy'><dir id='Anzwy'><q id='Anzwy'></q></dir></style></legend>

                          <bdo id='Anzwy'></bdo><ul id='Anzwy'></ul>
                          <tfoot id='Anzwy'></tfoot>

                            <small id='Anzwy'></small><noframes id='Anzwy'>

                            <i id='Anzwy'><tr id='Anzwy'><dt id='Anzwy'><q id='Anzwy'><span id='Anzwy'><b id='Anzwy'><form id='Anzwy'><ins id='Anzwy'></ins><ul id='Anzwy'></ul><sub id='Anzwy'></sub></form><legend id='Anzwy'></legend><bdo id='Anzwy'><pre id='Anzwy'><center id='Anzwy'></center></pre></bdo></b><th id='Anzwy'></th></span></q></dt></tr></i><div id='Anzwy'><tfoot id='Anzwy'></tfoot><dl id='Anzwy'><fieldset id='Anzwy'></fieldset></dl></div>