覆盖 C++ 虚拟方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9018077/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:12:50  来源:igfitidea点击:

override c++ virtual method

c++inheritanceoverridingvirtual-functions

提问by shn

I have a class template where some methods are defined as virtual to give the ability for the user of my class to give an implementation for them in his derived class. Note that in my template class there is some non-virtual methods that makes use of the virtual one (a virtual class that should return a value is called in a non-virtual class).

我有一个类模板,其中一些方法被定义为虚拟方法,以便我的类的用户能够在他的派生类中为它们提供实现。请注意,在我的模板类中,有一些非虚拟方法使用了虚拟方法(在非虚拟类中调用应该返回值的虚拟类)。

Can you give me a simple example of a correct code where the virtual method of the parent class should return a value (but it's implementation is provided in a child class) and the value returned by the virtual method in the parent class is used in other methods of that class. Because I saw somewhere (for example here: Safely override C++ virtual functions) that this can cause some problems and the user defined method will note override the virtual method of the parent class.

你能给我一个正确代码的简单例子,其中父类的虚方法应该返回一个值(但它的实现是在子类中提供的),而父类中的虚方法返回的值用于其他该类的方法。因为我在某处看到(例如这里:Safely override C++ virtual functions)这会导致一些问题,并且用户定义的方法会注意覆盖父类的虚方法。

Note: I program with Code::Blocks using g++ compiler.

注意:我使用 g++ 编译器使用 Code::Blocks 进行编程。

EDIT: as requested here a simple example of what I want:

编辑:根据这里的要求,我想要一个简单的例子:

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

The method compute() should be implemented by the user (the child class). However, this method compute() is called by putSomething() and doComplexeThings() for example.

方法compute() 应该由用户(子类)实现。但是,例如 putSomething() 和 doComplexeThings() 会调用此方法 compute()。

回答by mschneider

You just have to make sure that the methods have the same signature (including const/mutable modifiers and argument types). You can use a pure virtual definition to provoke compiler errors if you fail to override the function in a subclass.

您只需要确保这些方法具有相同的签名(包括 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
}

回答by David Rodríguez - dribeas

If you can use C++11 features in your compiler then overrides can be tagged as so with the overridespecial identifier:

如果您可以在编译器中使用 C++11 功能,则可以使用override特殊标识符标记覆盖:

 float compute() override;

The above line in a derived class will cause a compiler error as the function does not override a member function in the base (incorrect signature, missing argument). But note that this must be done in each derived class, it is not a solution that you can impose from the base class.

派生类中的上述行将导致编译器错误,因为该函数不会覆盖基中的成员函数(签名不正确,缺少参数)。但请注意,这必须在每个派生类中完成,这不是您可以从基类强加的解决方案。

From the base class you can only forcethe override by making the function pure virtual, but that changes the semantics. It does not avoidproblems while overriding, but rather forcesoverriding in all cases. I would avoid this approach, and if you are to follow it and there is a sensible implementation for the base type, make the function virtual andprovide a definition so that your derived classes's implementation can just call the functions the base type (i.e. you force the implementation, but in the simplest cases it will just forward the call to the parent)

从基类中,您只能通过使函数纯虚拟来强制覆盖,但这会改变语义。它不会在覆盖时避免问题,而是在所有情况下强制覆盖。我会避免这种方法,如果您要遵循它并且基类型有合理的实现,请将函数设为虚拟提供定义,以便您的派生类的实现可以只调用基类型的函数(即您强制实现,但在最简单的情况下,它只会将调用转发给父级)

回答by yuan

This question is asked in 2013. It's pretty old but I found something new which doesn't exist in the answers.

这个问题是在 2013 年提出的。它已经很老了,但我发现了一些答案中不存在的新问题。

We need to understanding three concept is overload, overwrite, and hide.

我们需要理解三个概念是重载覆盖隐藏

Short answer, you want to overload the inheritance function from base class. However, overload is the mechanism to add multiple behavior for function which needs all these functions under the same scale. But the virtual function is in the Base class obviously.

简短的回答,你想从基类重载继承函数。但是,重载是为需要所有这些函数的函数添加多个行为的机制。但虚函数显然在 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;
}

Add using A::print;in your derive class will do the work!

添加使用 A::print; 在您的派生类中将完成这项工作!

Though I don't feel it's a good idea since the philosophy behind the overloadand inheritanceis different, it may not a good idea to nest them together.

虽然我不认为这是一个好主意,因为重载继承背后的哲学是不同的,但将它们嵌套在一起可能不是一个好主意。