通过引用抛出非常量临时值 [英] Throwing non-const temporaries by reference

查看:211
本文介绍了通过引用抛出非常量临时值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过非const引用在try-block中引用在栈上构造的对象,捕获它并修改它,然后通过引用另一个catch块抛出一个对象是否有什么问题?

Is there any problem with throwing an object constructed on the stack in a try-block by non-const reference, catching it and modifying it, then throwing it by reference to another catch block?

下面是我要引用的一个简短示例。

Below is a short example of what I'm refering to.

struct EC {
    EC(string msg) { what = msg; }
    string where;
    string what;

    void app(string& t) { where += t; }
    string get() { return what; }
};

try {
    try {
        try {
            EC error("Test");
            throw error;
        }
        catch (EC& e) {
            e.app("1");
            throw e;
        }
    }
    catch (EC& e) {
        e.app("2");
        throw e;
    }
}
catch (EC& e) {
     e.app("3");
     cout << e.where << endl;
     cout << e.get() << endl;
}

这可能会导致e.what包含垃圾, 。保持完好?例如:$ b $bÚe.where是123
ought e.get()返回很多垃圾数据,直到碰到一个空字节。

Is it possible that this could cause e.what to contain junk, but e.where to remain intact? For example:
e.where is "123"
e.get() returns a lot of garbage data, until it happens to hit a null byte.

推荐答案

没有像throwing by reference这样的东西。这是不可能的。没有语法。每次尝试引用时,实际上都会抛出引用对象的副本。不必说,你的代码中没有尝试引用。

There's no such thing as "throwing by reference". It is simply impossible. There's no syntax for that. Every time you try to "throw a reference", a copy of the referenced object is actually thrown. Needless to say, there are no attempts to throw by reference in your code.

可以通过引用捕获甚至通过非常量),并通过它修改临时异常对象。它会工作。事实上,您可以重新抛出现在修改的现有异常对象,而不是创建一个对象。也就是说你可以只做

It is possible to catch a previously thrown exception by reference (even by a non-const one) and modify the temporary exception object through it. It will work. In fact, you can re-throw the now-modified existing exception object instead of creating a new one. I.e. you can just do

throw;

而不是

throw e;

,并且仍然获得正确的行为代码,即原始对象

in your catch clauses and still get the correctly behaving code, i.e. the original object (with modifications) will continue its flight throgh the handler hierarchy.

但是,您的代码在

e.app("1"); 

调用(以及对 app 的其他调用)因为参数是非常量引用。将 app 声明更改为

call (and other calls to app) since the parameter is non-const reference. Change the app declaration to either

void app(const string& t) { where += t; }  // <- either this
void app(string t) { where += t; }         // <- or this

否则,你的代码应该工作正常。你不应该从 get()获得任何垃圾。如果你这样做,它必须是你的编译器的问题,或者你的代码,你不显示。

Otherwise, you code should work fine. You are not supposed to get any garbage from get(). If you do, it must be either a problem with your compiler or with your code that you don't show.

这篇关于通过引用抛出非常量临时值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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