可能重复:
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函数专门告诉编译器它可以被覆盖?抱歉这个愚蠢的问题。 :/
答案 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 ++程序中错误的一个小来源。不同的语言对此有不同的看法。