加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C:在引用基类时,引用派生类不起作用

发布时间:2020-12-16 05:48:56 所属栏目:百科 来源:网络整理
导读:我想用基类异常抛出自己的异常.有一个虚拟方法打印将被子类覆盖.我只抓住了Exception并使用print来获取特定的错误.问题是,一旦我抛出一个子类的引用,就像它是基类一样. 这是一个例子: #include iostreamusing namespace std;class Exception{ public: virtu
我想用基类异常抛出自己的异常.有一个虚拟方法打印将被子类覆盖.我只抓住了Exception&并使用print来获取特定的错误.问题是,一旦我抛出一个子类的引用,就像它是基类一样.

这是一个例子:

#include <iostream>
using namespace std;

class Exception
{
    public:
        virtual void print()
        {
            cout << "Exception" << endl;
        }
};

class IllegalArgumentException : public Exception
{
    public:
        virtual void print()
        {
            cout << "IllegalArgumentException" << endl;
        }
};

int main(int argc,char **argv)
{
    try
    {
        IllegalArgumentException i;
        Exception& ref = i;

        cout << "ref.print: ";
        ref.print();

        throw ref;
    }
    catch(Exception& e)
    {
        cout << "catched: ";
        e.print();
    }
}

此示例的输出是:

ref.print: IllegalArgumentException
catched: Exception

使用引用将导致所使用的派生类的print方法.在try块中,引用确实使用它.为什么不抓住异常&像一个IllegalArgumentException一样,我该如何得到这个行为?

以下代码似乎做了它应该做的事情:

try
{
    IllegalArgumentException i;
    Exception* pointer = &i;

    throw pointer;
}
catch(Exception* e)
{
    cout << "pointer catched: ";
    e->print();
}

但是在try块的范围之外,指针是否变得可能无效?那么这样做是有风险的,如果我在堆上分配内存来解决这个问题,我有责任在catch块内删除不漂亮的东西.那么你如何解决这个问题呢?

解决方法

隐含地拷贝副本,从而切片.报价C 11,§15.1/ 3:

A throw-expression initializes a temporary object,called the exception object,the type of which is determined by removing any top-level cv-qualifiers from the static type of the operand of throw and adjusting the type from “array of T” or “function returning T” to “pointer to T” or “pointer to function returning T”,respectively. The temporary is an lvalue and is used to initialize the variable named in the matching handler. If the type of the exception object would be an incomplete type or a pointer to an incomplete type other than (possibly cv-qualified) void the program is ill-formed. Except for these restrictions and the restrictions on type matching mentioned in 15.3,the operand of throw is treated exactly as a function argument in a call or the operand of a return statement.

我已经看到了一些代码库,通过抛出指向异常的指针,而不是直接对象来解决这个问题,但是我个人只是重新考虑你的“需要”来做到这一点.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读