C ++ VIRTUAL函数如何不冗余?

时间:2010-10-14 06:28:59

标签: c++ virtual virtual-functions

  

可能重复:
  Overriding vs Virtual
  How am i overriding this C++ inherited member function without the virtual keyword being used?

我现在正在学习C ++,但在编程语言时我并不是完全处于黑暗中。对我来说没有任何意义。我的理解是类中的VIRTUAL函数可以在子类中重写。但是,默认情况下不允许这样做吗?例如:

class Color {
    public:
        void Declare() { std::cout <<"I am a generic color."; }
};

class Purple : public Color {
};

如果我创建一个Purple实例然后调用它的Declare函数,那么它显然会输出控制台窗口“我是一般颜色”。如果我想在Purple类中重写这个函数,我可以在那里定义它来生成:

class Purple : public Color {
    public:
        void Declare() { std::cout <<"I am purple."; }
};

当然,这会输出“我是紫色的”。到控制台。如果我可以默认覆盖函数,那么有什么能让VIRTUAL函数专门告诉编译器它可以被覆盖?抱歉这个愚蠢的问题。 :/

6 个答案:

答案 0 :(得分:3)

考虑以下代码:

class Color
{
public:
    void Declare() { std::cout << "I am a generic color"; }
};

class Purple : public Color
{
public:
    void Declare() { std::cout << "I am purple"; }
}

Color* color = new Purple();
color->Declare();

如上所述,这将打印出“我是一般颜色”,即通过基类指针(Color*)调用Declare()将调用基类的函数实现。

如果您在virtual的Declare()声明前添加关键字Color,则会打印“我是紫色”。 virtual关键字告诉编译器应该通过基类指针调用函数到具体类(Purple)实现。

答案 1 :(得分:1)

虚函数在处理多态时很有用。在编译时查找非虚函数,因此创建类型为Color的变量并调用其Declare()方法将始终导致调用Color::Declare(),即使变量中的对象是Purple

答案 2 :(得分:1)

不同之处在于,如果你有一个函数foo,它采用一种颜色并调用它的声明方法,如果它们是虚拟的,你传入一个紫色,它会说我是紫色的,如果方法不是虚拟的,它会说我是一般颜色...

答案 3 :(得分:1)

虚函数允许多态 - 你可以有一个指向 base 类的指针,它仍然在派生类中调用该函数。在你的例子中

Color *c=new Purple;
c->Declare();

将输出“我是一般颜色”。如果Declare()中的Color函数为virtual,则Purple中的函数将覆盖,因此此代码将打印出“我是紫色的。“

答案 4 :(得分:1)

重要的区别在于这种情况会发生什么:

Purple p;
Color* pC = &p;
pc->Declare();

如果函数Declare被定义为非虚拟,那么调用将调用转到基类。如果函数被指定为virtual,则调用将转到派生类。因此,使用函数将允许您使用基类指针调用派生类方法。基本上它支持polymorphism

答案 5 :(得分:0)

不,这不是多余的。

尝试:

Color* color = new Purple();
color->Declare();

你想要它打印“我是紫色的”。只有当您将Declare声明为虚拟时,才会发生这种情况。

允许在派生类中覆盖函数名而不是虚拟函数的选择是C ++程序中错误的一个小来源。不同的语言对此有不同的看法。