同名继承函数和重写虚函数有什么区别?

发布于 2024-09-24 16:57:00 字数 832 浏览 3 评论 0原文

#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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

动听の歌 2024-10-01 16:57:00

重点是获得多态行为。如果基类中的函数被声明为虚函数,并且派生类重写了它,那么如果您使用类指针调用该函数,它将自动调用派生类中的函数。如果它不是虚拟的,那么它将调用基类函数。

基本思想是这样你就可以做这样的事情:

class Animal
{
    public:
    virtual void talk() = 0;
};

class Dog : public Animal
{
    public:
    void talk() { cout << "Bark" << endl; }
};

class Cat : public Animal
{
    public:
    void talk() { cout << "Meow" << endl; }
};

void foo(Animal* a)
{
    a->talk();
}

现在,当你将 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:

class Animal
{
    public:
    virtual void talk() = 0;
};

class Dog : public Animal
{
    public:
    void talk() { cout << "Bark" << endl; }
};

class Cat : public Animal
{
    public:
    void talk() { cout << "Meow" << endl; }
};

void foo(Animal* a)
{
    a->talk();
}

Now when you pass an Animal pointer to foo() and invoke the talk() member function, it will do something different depending on whether it points to a Cat object or a Dog object. The point is that foo() is able to work with anything that inherits from Animal. Plus, if some time later you create a new kind of Animal class, you can pass it to foo() with no problem and without having to modify any code inside foo().

残花月 2024-10-01 16:57:00

只有当您使用指针或引用时,您才会看到两者之间的区别。

deriv * d = new deriv;
d->f(); // "deriv"
d->v(); // "deriv (overridden)"

正如预期的那样。现在我们将此指针转换为基指针:

base * b = static_cast<base *>(d);
b->f(); // "base"
b->v(); // "deriv (overridden)"

即使该指针是指向基类的指针,虚拟函数调用也会转到派生函数。

You'll only see the difference between the two when you're using a pointer or reference.

deriv * d = new deriv;
d->f(); // "deriv"
d->v(); // "deriv (overridden)"

As expected. Now we cast this pointer to a base pointer:

base * b = static_cast<base *>(d);
b->f(); // "base"
b->v(); // "deriv (overridden)"

The virtual function call goes to the derived function, even though the pointer is a pointer to the base class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文