Бросать неконстантные временные ссылки - PullRequest
1 голос
/ 16 февраля 2010

Есть ли проблема с бросанием объекта, созданного в стеке в блоке try, по неконстантной ссылке, перехватом и модификацией, а затем с пересылкой по ссылке на другой блок catch?

Ниже приведен краткий пример того, к чему я обращаюсь.

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.where это "123"
e.get () возвращает много мусорных данных, пока не произойдет попадание в нулевой байт.

1 Ответ

6 голосов
/ 16 февраля 2010

Нет такой вещи, как "бросок по ссылке". Это просто невозможно. Там нет синтаксиса для этого. Каждый раз, когда вы пытаетесь «сгенерировать ссылку», копия ссылочного объекта фактически выбрасывается. Излишне говорить, что в вашем коде нет попыток бросить по ссылке.

Можно перехватить ранее сгенерированное исключение по ссылке (даже неконстантной) и изменить через него объект временного исключения. Это будет работать. Фактически, вы можете перебросить измененный теперь существующий объект исключения вместо создания new . То есть Вы можете просто сделать

throw;

вместо

throw e;

в ваших предложениях catch и по-прежнему получайте код с правильным поведением, то есть исходный объект (с изменениями) продолжит свой полет через иерархию обработчиков.

Тем не менее, ваш код неправильно сформирован на

e.app("1"); 

вызов (и другие вызовы app), поскольку параметр является неконстантной ссылкой. Измените объявление app на

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

для компиляции.

В противном случае ваш код должен работать нормально. Вы не должны получать мусор от get(). Если вы это сделаете, это может быть проблемой вашего компилятора или вашего кода, который вы не показываете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...