同名继承函数和重写虚函数有什么区别?
#include <iostream>
using namespace std;
class base
{
public:
void f() {cout << "base" << endl;}
virtual void v() {cout << "base (virtual)" << endl;}
};
class deriv : public base
{
public:
void f() {cout << "deriv" << endl;}
void v() {cout << "deriv (overridden)" << endl;}
};
int main()
{
base b;
b.f();
b.v();
deriv d;
d.f();
d.v();
}
我不明白这两种方法 f 和 v 之间有什么真正的区别:如果我用另一个同名的函数替换一个函数,我不是“替换”它吗?即使我仍然可以通过创建一个 base* 指针然后使其指向 deriv 对象来访问它,我也不明白这里有什么样的 C++ “干净”用法。
当不使用虚拟(意味着可重写方法)方法时,有人可以告诉我这是否有合法用途,以及与使用重写虚拟方法有什么不同?
编辑:我很抱歉在 markdown 中使用了错误的语法,但 markdown 是一个非常糟糕的选择,它很复杂而且很反复无常(我更喜欢纺织嘿嘿)。 EDIT2:抱歉,我没有猜到 101010101010101 按钮意味着插入代码,我通常只是手动完成:(
#include <iostream>
using namespace std;
class base
{
public:
void f() {cout << "base" << endl;}
virtual void v() {cout << "base (virtual)" << endl;}
};
class deriv : public base
{
public:
void f() {cout << "deriv" << endl;}
void v() {cout << "deriv (overridden)" << endl;}
};
int main()
{
base b;
b.f();
b.v();
deriv d;
d.f();
d.v();
}
I don't understand what real difference is there between those two methods f and v: if I replace a function with another with the same name, am I not "replacing" it ? Even if I can still access it by creating a base* pointer and then make it point to a deriv object, I don't understand what kind of "clean" use of C++ there is here.
When not using virtual (meaning overriddable methods) methods, can somebody tell me if there is a legitimate use for this, and what is different from using overridden virtual method ?
EDIT: I'm sorry using bad syntax with markdown, but markdown is a really bad choice, it's complicated and quite capricious (I prefer textile hehe).
EDIT2: Sorry I didn't guess 101010101010101 button meant to insert code, I usually just do it by hand :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
重点是获得多态行为。如果基类中的函数被声明为虚函数,并且派生类重写了它,那么如果您使用基类指针调用该函数,它将自动调用派生类中的函数。如果它不是虚拟的,那么它将调用基类函数。
基本思想是这样你就可以做这样的事情:
现在,当你将 Animal 指针传递给 foo() 并调用
talk()
成员函数时,它会做一些事情根据它指向Cat
对象还是Dog
对象而有所不同。关键是foo()
能够处理从Animal
继承的任何内容。另外,如果一段时间后您创建了一种新的Animal
类,您可以将其传递给foo()
,没有任何问题,而无需修改中的任何代码>foo()
。The point is to get polymorphic behavior. If a function in a base-class is declared virtual, and a derived class overrides it, if you call the function using a base class pointer it will automatically call the function in the derived class. If it's not virtual, then it will call the base-class function.
The basic idea is so you can do things like this:
Now when you pass an Animal pointer to
foo()
and invoke thetalk()
member function, it will do something different depending on whether it points to aCat
object or aDog
object. The point is thatfoo()
is able to work with anything that inherits fromAnimal
. Plus, if some time later you create a new kind ofAnimal
class, you can pass it tofoo()
with no problem and without having to modify any code insidefoo()
.只有当您使用指针或引用时,您才会看到两者之间的区别。
正如预期的那样。现在我们将此指针转换为基指针:
即使该指针是指向基类的指针,虚拟函数调用也会转到派生函数。
You'll only see the difference between the two when you're using a pointer or reference.
As expected. Now we cast this pointer to a base pointer:
The virtual function call goes to the derived function, even though the pointer is a pointer to the base class.