2014-11-04 35 views
9

我对派生类中重新定义和重写函数之间的区别感到困惑。在C++中重新定义与重写

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

当一个派生类“重新定义”了一个基类中的方法时,其被重新定义。但是当派生类是虚拟的时,它不再重新定义,而是重写。所以我理解规则的后勤,但我不明白底线。

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

基类:

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

派生类:

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

这是主要:

// Define a CurvedActivity object. 
    CurvedActivity exam; 

    ... 

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

覆盖有助于类多态性。重载有利于函数多态性。重新定义既不会也是错误。 – orfdorf 2014-11-04 20:10:47

回答

14

这里有一些基本的不同之处:

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

安装覆盖函数是一个后代类中的方法,它具有与祖先类中的虚拟函数不同的定义。编译器根据用于调用该函数的对象的类型来选择所需的函数。

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

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

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

+0

谢谢,这可能是愚蠢的,但这是什么意思:静态类型的对象引用。 – YelizavetaYR 2014-11-04 20:10:26

+0

只有在相同范围内,函数才会重载。可能想补充一点。 – Deduplicator 2014-11-04 20:10:37

+3

*“编译器根据用于调用函数的对象的类型来选择所需的函数。”*这是不正确的,编译器不会做出任何决定。这个决定是在运行时通过vtable查找完成的。 – Manu343726 2014-11-04 20:11:21