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

前端之家收集整理的这篇文章主要介绍了C:在引用基类时,引用派生类不起作用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我想用基类异常抛出自己的异常.有一个虚拟方法打印将被子类覆盖.我只抓住了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.

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

猜你在找的C&C++相关文章