簡體   English   中英

覆蓋c ++虛方法

[英]override c++ virtual method

我有一個類模板,其中一些方法被定義為虛擬,以使我的類的用戶能夠在他的派生類中為它們提供實現。 請注意,在我的模板類中,有一些非虛擬方法使用虛擬方法(應該在非虛擬類中調用應該返回值的虛擬類)。

你能給我一個正確代碼的簡單例子,其中父類的虛方法應返回一個值(但它的實現是在子類中提供的),而父類中的虛方法返回的值則用於其他該類的方法。 因為我看到某處(例如這里: 安全地覆蓋C ++虛函數 )這會導致一些問題,用戶定義的方法會注意覆蓋父類的虛方法。

注意:我使用g ++編譯器使用Code :: Blocks編程。

編輯:根據要求,我想要一個簡單的例子:

template<typename T>
class parent {
public:
  // Public methods that user can call
  int getSomething(T t);
  void putSomething(T t, int x);

  // public method that user should implement in his code
  virtual float compute(T t) { }

  // protected or private methods and attributes used internally by putSomething ...
  float doComplexeThings(...); // this can call
};

方法compute()應該由用戶(子類)實現。 但是,此方法compute()由putSomething()和doComplexeThings()調用。

您只需確保方法具有相同的簽名(包括const / mutable修飾符和參數類型)。 如果未能覆蓋子類中的函數,則可以使用純虛擬定義來激發編譯器錯誤。

class parent {
public:
  // pure virtual method must be provided in subclass
  virtual void handle_event(int something) = 0; 
};

class child : public parent {
public:
  virtual void handle_event(int something) {
    // new exciting code
  }
};

class incomplete_child : public parent {
public:
  virtual void handle_event(int something) const {
    // does not override the pure virtual method
  }
};

int main() {
  parent *p = new child();
  p->handle_event(1); // will call child::handle_event
  parent *p = new incomplete_child(); // will not compile because handle_event
                                      // was not correctly overridden
}

如果您可以在編譯器中使用C ++ 11功能,則可以使用override特殊標識符標記override

 float compute() override;

派生類中的上述行將導致編譯器錯誤,因為該函數不會覆蓋基類中的成員函數(錯誤簽名,缺少參數)。 但請注意,這必須在每個派生類中完成,它不是可以從基類強加的解決方案。

從基類中,您只能通過使函數純虛擬來強制覆蓋,但這會更改語義。 它在覆蓋時不會避免問題,而是在所有情況下強制覆蓋。 我會避免這種方法,如果你要遵循它並且有一個合理的基類型實現,使函數虛擬提供一個定義,以便派生類的實現可以只調用函數基類型(即你強制實現,但在最簡單的情況下,它只會將調用轉發給父母)

這個問題在2013年被問到。它已經很老了,但我找到了一些在答案中不存在的新東西。

我們需要理解三個概念是重載覆蓋隱藏

簡而言之,您希望從基類重載繼承函數。 但是,重載是為函數添加多個行為的機制,它需要在相同規模下的所有這些函數。 但虛擬功能顯然在Base類中。

class A {
public:
  virtual void print() {
    cout << id_ << std::endl;
  }
private:
  string id_ = "A";
};

class B : A {
public:
  using A::print;
  void print(string id) {
    std::cout << id << std::endl;
  }
};

int main(int argc, char const *argv[]) {
  /* code */
  A a;
  a.print();
  B b;
  b.print();
  b.print("B");
  return 0;
}

使用A :: print添加; 在你的派生課上會做的工作!

雖然我覺得這不是一個好主意,因為重載繼承背后的哲學是不同的,將它們嵌套在一起可能不是一個好主意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM