C++-请问异常处理可不可以实现多态?怎么做?

UI设计界面 UI设计界面 主题:1059 回复:2190

C++-请问异常处理可不可以实现多态?怎么做?

泛泛之交 发布于 2017-05-14 字数 723 浏览 1043 回复 1

新人第一次提问,有不妥之处请各位老师见谅!

我先从Except里派生了Except1和Except2:

#ifndef EXCEPT_H
#define EXCEPT_H

class Except{
public:
Except(){}
virtual ~Except(){}

virtual const char* what() const{
return "Ex!";
}
};

class Except1: public Except{
public:
Except1(){}
virtual ~Except1(){}

virtual const char* what() const{
return "Ex1!";
}
};

class Except2: public Except{
public:
Except2(){}
virtual ~Except2(){}

virtual const char* what() const{
return "Ex2!";
}
};

#endif

发布评论

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

支持 Markdown 语法,需要帮助?

评论(1

晚风撩人 2017-10-23 1 楼

这是一个不是问题的问题,简单的说,犯了一个简单的错误,throw &Except1();,这里构造了一个局部对象,在栈上,返回的时候,这个对象已经被销毁了,换成throw (new Except1);这种方式就不会出现你所谓的问题,也不存在“异常处理可不可以实现多态”这种奇怪的题目。

稍微延伸一点说,为什么会输出"Ex!"。在throw &Except1();的时候,这个对象的续表指针指向的是Except1的虚表,假设该续表地址0x455004,其中的what方法的地址假设为0x455110,指向的是Except1的what方法,如果在这里直接调用该对象的what方法输出的一定是"EX1!",实现多态。当返回该对象的指针到cout<<ex->what()<<endl;的时候,这个对象已经不存在了,只是指向的存储没有被使用而已,其中的续表地址不再是Except1的0x455004,而是Except的虚表地址,执行的自然是Except的what方法。

虚表是由编译器产生,链接器初始化的,非对象相关,这里析构函数和构造函数所做的只是使虚表指针指向正确的位置,所以局部对象销毁之后,将会改写续表指针的指向,析构的时候是先子类后父类,父类析构的时候也会首先重置虚表指针,所以即使对象销毁了,你还可以看到调用了父对象的what方法。