关于虚拟方法的问题

发布于 2024-08-31 14:57:28 字数 526 浏览 8 评论 0原文

如果两个方法都声明为虚拟方法,那么调用的 Method1() 的两个实例不应该都是派生类的 Method1() 吗?

我每次都会看到 BASE 然后 DERIVED 被调用。我正在为一次面试做一些回顾,我想确保我能弄清楚这一点。 xD

class BaseClass
{
public:
    virtual void Method1()  { cout << "Method 1 BASE" << endl; }
};

class DerClass: public BaseClass
{
public:
    virtual void Method1() { cout << "Method 1 DERVIED" << endl; }
};


DerClass myClass;
    ((BaseClass)myClass).Method1();
    myClass.Method1();

方法 1 基础
方法1衍生

IF both methods are declared as virtual, shouldn't both instances of Method1() that are called be the derived class's Method1()?

I am seeing BASE then DERIVED called each time. I am doing some review for an interview and I want to make sure I have this straight. xD

class BaseClass
{
public:
    virtual void Method1()  { cout << "Method 1 BASE" << endl; }
};

class DerClass: public BaseClass
{
public:
    virtual void Method1() { cout << "Method 1 DERVIED" << endl; }
};


DerClass myClass;
    ((BaseClass)myClass).Method1();
    myClass.Method1();

Method 1 BASE
Method 1 DERVIED

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(5

单调的奢华 2024-09-07 14:57:28

不,“C 风格”转换 ((BaseClass)myClass) 通过对 myClass 进行切片来创建临时 BaseClass 对象。它的动态类型是BaseClass,它根本不是DerClass,因此被调用的Method1是基类方法。

myClass.Method1() 是直接调用。由于 myClass 是一个对象,而不是引用,因此没有虚拟调度(不需要)。

No, the "C-style" cast ((BaseClass)myClass) creates a temporary BaseClass object by slicing myClass. It's dynamic type is BaseClass, it isn't a DerClass at all so the Method1 being called is the base class method.

myClass.Method1() is a direct call. As myClass is an object, not a reference there is no virtual dispatch (there would be no need).

无人问我粥可暖 2024-09-07 14:57:28

不可以,因为虚函数机制仅在通过指针或引用调用函数时才起作用。否则,将使用对象的静态类型来确定要调用哪个函数。

No, because the virtual function mechanism only works if a function is called via a pointer or a reference. Otherwise the static type of the object is used to determine which function to call.

风筝有风,海豚有海 2024-09-07 14:57:28

您在这里看到的称为“切片”。将派生类的对象转换为基类会“切掉”不属于基类的所有内容。

在 C++ 中,虚函数仅适用于指针或引用。为了使您的示例正常工作,您必须执行以下操作:


DerClass myClass;
((BaseClass *) &myClass)->Method1();

或者您可以这样做


BaseClass *pBase = new DerClass;
pBase->Method1();

What you are seeing here is called "slicing". Casting an object of the derived class to the base class "slices off" everything that is not in the base class.

In C++ virtual functions work correctly only for pointers or references. For your example to work right, you have to do the following:


DerClass myClass;
((BaseClass *) &myClass)->Method1();

Or you could do


BaseClass *pBase = new DerClass;
pBase->Method1();

眼角的笑意。 2024-09-07 14:57:28

由于转换 ((BaseClass)myClass)myClass 对象从 DerClass 切片为 BaseClass,因此只有 <调用 code>BaseClass 的 Method1() 实现。

为了使多态性正常工作,您必须通过指针:

DerClass myClass; 
BaseClass* ptrToMyClass = &myClass;
ptrToMyClass->Method1(); // Calls the DerClass implementation of Method1()

或引用调用方法:

DerClass myClass; 
BaseClass& refToMyClass = myClass;
refToMyClass.Method1();  // Calls the DerClass implementation of Method1()

Because the cast ((BaseClass)myClass) slices the myClass object from DerClass to BaseClass, so only the BaseClass's implementation of Method1() is called.

For polymorphism to work properly, you must call the methods via pointers:

DerClass myClass; 
BaseClass* ptrToMyClass = &myClass;
ptrToMyClass->Method1(); // Calls the DerClass implementation of Method1()

or references:

DerClass myClass; 
BaseClass& refToMyClass = myClass;
refToMyClass.Method1();  // Calls the DerClass implementation of Method1()
素手挽清风 2024-09-07 14:57:28

((BaseClass)myClass).Method1(); -->对象切片因此总是会调用基类方法。
真正的多态行为是通过基类指针实现的,基类指针可以包含派生类的任何对象。
因此,要实现您想要的目标,您需要传递派生类对象的地址并将其类型化为基类指针。如下:
((BaseClass *) &myClass)->Method1();

((BaseClass)myClass).Method1(); --> object slicing hence always base class method will get called.
Real polymorphic behaviour is achieved through base class pointer which can contain any objects of derived classes.
Hence to achieve what you want you need to do pass address of derived class object and typecase it to base class pointer. as below:
((BaseClass *) &myClass)->Method1();

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