在 C++ 中重新定义与覆盖

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26743991/
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-28 11:40:58  来源:igfitidea点击:

Redefining vs. Overriding in C++

c++classinheritancebasederived

提问by YelizavetaYR

I am confused about the differences between redefining and overriding functions in derived classes.

我对派生类中重新定义和覆盖函数之间的差异感到困惑。

I know that - In C++, redefined functions are statically bound and overridden functions are dynamically bound and that a a virtual function is overridden, and a non-virtual function is redefined.

我知道 - 在 C++ 中,重新定义的函数是静态绑定的,被覆盖的函数是动态绑定的,并且虚拟函数被覆盖,非虚拟函数被重新定义。

When a derived class "redefines" a method in a base class its considered redefining. But when a derived class is virtual it no longer redefines but rather overrides. So i understand the logistics of the rules but i don't understand the bottom line.

当派生类“重新定义”基类中的方法时,它被认为是重新定义。但是当派生类是虚拟的时,它不再重新定义而是覆盖。所以我了解规则的物流,但我不了解底线。

In the below example the function SetScore is redefined. However if I make the setScore function in the base class virtual (by adding the word virtual to it) the setScore in the derived class will be overridden. I don't understand the bottom line - what is the difference. in setScore?

在下面的例子中,函数 SetScore 被重新定义。但是,如果我将基类中的 setScore 函数设为虚拟(通过向其添加虚拟一词),派生类中的 setScore 将被覆盖。我不明白底线 - 有什么区别。在 setScore 中?

The base class:

基类:

class GradedActivity
{
protected:
   char letter;            // To hold the letter grade
   double score;           // To hold the numeric score
   void determineGrade();  // Determines the letter grade
public:
   // Default constructor
   GradedActivity()
  { letter = ' '; score = 0.0; }

 // Mutator function
   void setScore(double s) 
      { score = s;
        determineGrade();}

   // Accessor functions
   double getScore() const
      { return score; }

       char getLetterGrade() const
      { return letter; }
};

The derived class:

派生类:

class CurvedActivity : public GradedActivity
{
protected:
   double rawScore;     // Unadjusted score
   double percentage;   // Curve percentage
public:
   // Default constructor
   CurvedActivity() : GradedActivity()
      { rawScore = 0.0; percentage = 0.0; }

   // Mutator functions
   void setScore(double s) 
      { rawScore = s;
        GradedActivity::setScore(rawScore * percentage); }

   void setPercentage(double c)
      { percentage = c; }

   // Accessor funtions
   double getPercentage() const
      { return percentage; }

   double getRawScore() const
      { return rawScore; }
};

This is main:

这是主要的:

   // Define a CurvedActivity object.
   CurvedActivity exam;

   ... 

   // Send the values to the exam object.
   exam.setPercentage(percentage);
   exam.setScore(numericScore);

回答by Lawrence Aiello

Here are some basic differences:

以下是一些基本区别:

An overloadedfunction is a function that shares its name with one or more other functions, but which has a different parameter list. The compiler chooses which function is desired based upon the arguments used.

一个重载函数是一个函数,分享它的名字与一个或多个其他功能,但具有不同的参数列表。编译器根据使用的参数选择所需的函数。

An overriddenfunction is a method in a descendant class that has a different definition than a virtual function in an ancestor class. The compiler chooses which function is desired based upon the type of the object being used to call the function.

重写功能是在具有比在祖先类的虚拟函数不同的定义子类中的方法。编译器根据用于调用函数的对象类型来选择所需的函数。

A redefinedfunction is a method in a descendant class that has a different definition than a non-virtual function in an ancestor class. Don't do this. Since the method is not virtual, the compiler chooses which function to call based upon the static type of the object reference rather than the actual type of the object.

定义函数是后代类中的方法,其定义与祖先类中的非虚拟函数不同。不要这样做。由于该方法不是虚拟的,编译器根据对象引用的静态类型而不是对象的实际类型来选择调用哪个函数。

  • Static type checkingmeans that type checking occurs at compile time. No type information is used at runtime in that case.

  • Dynamic type checkingoccurs when type information is used at runtime. C++ uses a mechanism called RTTI (runtime type information) to implement this. The most common example where RTTI is used is the dynamic_cast operator which allows downcasting of polymorphic types:

  • 静态类型检查意味着在编译时进行类型检查。在这种情况下,在运行时不使用任何类型信息。

  • 在运行时使用类型信息时会发生动态类型检查。C++ 使用一种称为 RTTI(运行时类型信息)的机制来实现这一点。使用 RTTI 的最常见示例是 dynamic_cast 运算符,它允许向下转换多态类型: