C ++继承:指向基类的派生类指针调用派生类方法 [英] C++ Inheritance: Derived class pointer to a Base class invokes Derived class method

查看:136
本文介绍了C ++继承:指向基类的派生类指针调用派生类方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习C ++继承,因此我尝试通过动态创建一个基类并对该基类进行向下转换(显然对向下转换无效)来尝试使用此代码,以使此动态创建的基对象由a指向.派生类指针.但是,当我通过此派生指针调用方法who()时,它将调用派生类方法而不是基类方法.

I am learning C++ inheritance, so I tried this code by creating a Base class dynamically and made a downcast to its Derived class (obviously its not valid to downcast) in order to make this dynamically created Base object to be pointed by a Derived class pointer. But when I call a method who() through this Derived pointer it invokes the Derived class method instead of Base class method.

根据我的假设,没有为派生类创建任何对象,那么怎么可能调用未创建的派生类对象的方法而不是实际创建的基类对象呢?

According to my assumption no object is created for the Derived class, then how could it be possible to invoke the non created Derived class object's method instead of actually created Base class object?

我用谷歌搜索了这种现象,但是找不到调用未创建的派生类对象的方法的清晰明了的解释.如果符合标准,请向我解释其工作原理. 我知道如果我使用方法virtual,故事会有所不同,但此处使用的方法不是virtual.

I googled for this phenomenon but couldn't find a clear and crispy explanation for invoking a non created Derived class object's method. If it is according to the standard then explain me how it works. I know the story will be different if I make the method virtual but the method used here is not virtual.

class parent{
    public:
        void who(){
            cout << "I am parent";
        }
};

class child : public parent{
    public:
        void who(){
            cout << "I am child";
        }
};

int main(){
    child *c = (child *)new parent();
    c->who();
    return 0;
}

输出为I am child,但我希望为I am parent

修改:: 我没有释放上面代码中的内存并进行了无效的下调,因为我只是想看看会发生什么.因此,仅说明这种调用方法的行为.

: I didn't freed up the memory in the above code and made an invalid downcast because I just wanted to see what happens. So just explain this behavior of invoking methods only.

推荐答案

@Mark Ransom 所建议的那样这些评论后,我查看了帖子何时在空实例上调用成员函数会导致未定义的行为?.然后我想出了自己的解决方案.

As @Mark Ransom has suggested in the comments, I looked the post When does invoking a member function on a null instance result in undefined behavior?. Then I came up with my own solution.

使用parent类或child类或向下转换或继承,调用非创建对象的方法的行为与事实无关.我曾被静态告知要向下转换来调用child::who(),编译器会在不关心对象类型的情况下调用child::who().

This behavior of invoking a non created object's method is not a matter of fact with the parent class nor child class or downcast or inheritance . I had statically told to call the child::who() by downcasting, the compiler calls child::who() without caring about the object type.

但是,由于没有为child类创建对象,因此如何调用who()方法?

But how the who() method is called since no object is created for child class?

我尝试调用的方法没有任何成员变量,因此不需要取消引用this指针.它只是调用who(),如果child类指针也指向NULL,则相同的行为也适用.

The method which I tried to invoke doesn't have any member variable so there is no need to dereference this pointer. It just calls who(), the same behavior is true if the child class pointer points to NULL also.

child *c = NULL;
c->who(); 

即使c指向NULL,它也会打印I am child.因为不需要取消引用this指针.假设who()方法包含如下成员变量x的情况.

It prints I am child even though c points to NULL. Because no need to dereference this pointer. Lets have a situation where who() method contains a member variable x as below.

class child : public parent{
    private:
        int x;
    public:
        void who(){
            x = 10;
            cout << "I am child " << x;
        }
};

child *c = NULL;
c->who()

现在它会导致Segmentation fault,因为为了使用x,编译器必须将x的this指针取消引用为(*this).x.由于this指向NULL,因此取消引用将导致Segmentation fault.这显然是未定义的行为.

Now it causes Segmentation fault because in order to use x the compiler have to dereference this pointer for x as (*this).x. Since this points to NULL dereferencing will cause Segmentation fault. This is clearly an undefined behavior.

这篇关于C ++继承:指向基类的派生类指针调用派生类方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆