C ++ RAII не работает?

Вы пытались перенаправить внутри самой функции выхода из системы? Например, скажем, что ваша функция выхода из системы следующая

$scope.logout = function()
{
  $scope.userSession = undefined;
  window.location = "http://www.yoursite.com/#"
}

Тогда вы можете просто

<a ng-click="logout()">Sign out</a>
13
задан John 9 July 2009 в 14:08
поделиться

10 ответов

У вас нет обработчика исключения. Когда это происходит, стандарт говорит, что вызывается std :: terminate, который, в свою очередь, вызывает abort. См. Раздел 14.7 в языке программирования C ++, 3-е издание.

20
ответ дан 1 December 2019 в 17:20
поделиться

Проблема в том, что main имеет особый статус. Когда оттуда генерируется исключение, стек нельзя полностью развернуть, вместо этого приложение просто вызывает std: terminate .

И тогда становится понятным, почему переменные не выходят за рамки. Мы фактически не вышли из области, в которой они были объявлены . То, что происходит, можно считать эквивалентным следующему:

int main(void) {
  A a1(1);
  A a2(2);
  std::terminate();
}

(я считаю, что в данном случае вызываются ли деструкторы в зависимости от реализации, поэтому на некоторых платформах это будет работать так, как вы ожидали)

17
ответ дан 1 December 2019 в 17:20
поделиться

У вас есть необработанное исключение в главном файле, что означает завершение вызова. Попробуйте следующее:

int main(void)
{
    try
    {
        A a1(1);
        A a2(2);
        throw std::exception();
        return 0;
    }
    catch(const std::exception & e)
    {
        return 1;
    }


}
6
ответ дан 1 December 2019 в 17:20
поделиться

Если исключение ускользает из main (), это определяется реализацией, когда стек будет развернут.

попробуйте

int main()
{
    try
    {
        doWork(); // Do you experiment here. 
    }
    catch(...)
    {   /*
         * By catching here you force the stack to unwind correctly.
         */
        throw;  // re-throw so exceptions pass to the OS for debugging.
    }
}
6
ответ дан 1 December 2019 в 17:20
поделиться

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

Я собираюсь объяснить немного больше. Если исключение «всплывает» наверх, стек разматывается (редактировать). Даже перенос кода во второстепенную функцию не решит эту проблему. Пример:

      1 #include <exception>
      2 #include <iostream>
      3
      4 void test();
      5
      6 class A {
      7     public:
      8         A(int i) { i_ = i; std::cout << "A " << i_ << " constructed" << std::endl; }
      9         ~A() { std::cout << "A " << i_ << " destructed" << std::endl; }
     10     private:    int i_;
     11 };
     12
     13
     14 int main(void) {
     15     test();
     16     return 0;
     17 }
     18
     19 void test(){
     20             A a1(1);
     21             A a2(2);
     22            throw std::exception();
     23 }

Приведенный выше код не решит проблему. Единственный способ решить эту проблему - обернуть выброшенное исключение в блок try-catch. Это предотвратит попадание исключения в основную часть и остановит завершение, которое происходит до того, как объекты выйдут за пределы области видимости.

3
ответ дан 1 December 2019 в 17:20
поделиться

Поскольку исключение не обрабатывается к моменту достижения main (), оно приводит к вызову std :: terminate (), по сути, у вас есть эквивалент

int main(void) {
  A a1(1);
  A a2(2);
  exit(1);
}

Деструкторы НЕ гарантированно вызывается в случаях, когда программа завершается до того, как они выйдут из области видимости. Что касается еще одной дыры в RAII, рассмотрите:

int main(void) {
  A *a1 = new A(1);
}
0
ответ дан 1 December 2019 в 17:20
поделиться

Другие предлагали поместить try / catch внутри main () , чтобы справиться с этим, что отлично работает. По какой-то причине я считаю, что редко используемый «function-try-block» выглядит лучше, что меня удивляет (я думал, это будет выглядеть слишком странно). Но я не думаю, что есть какое-то реальное преимущество:

int main(void) 
try
{
    A a1(1);
    A a2(2);
    throw std::exception();
    return 0;
}
catch (...) 
{
    throw;
}

Пара недостатков состоит в том, что поскольку он редко используется, многие разработчики зацикливаются, когда видят его, и VC6 подавляется этим, если это необходимо.

1
ответ дан 1 December 2019 в 17:20
поделиться

Как указывали другие, у вас есть неперехваченное исключение, которое вызывает terminate (). Это определяется реализацией (см. Стандарт, 15.3 параграф 9 и 15.5.1 параграф 2), вызываются ли деструкторы в этом случае, и определение в вашей реализации, очевидно, «Нет, они не будут». (Если terminate () вызывается по любой другой причине, кроме генерации исключения, у которого нет обработчика, деструкторы не будут вызываться.)

5
ответ дан 1 December 2019 в 17:20
поделиться

Ваши объекты A не уничтожаются, потому что вызывается std :: terminate.

std :: terminate вызывается, когда необработанное исключение утекает из main. Если вы заключите свой код в команду try / catch (даже если catch просто повторно поднимет рейз), вы увидите ожидаемое поведение.

4
ответ дан 1 December 2019 в 17:20
поделиться
  1. Когда посетитель попадет на вашу страницу, создайте содержимое, отправьте его пользователю и сохраните статический файл где-нибудь на диске.
  2. Когда придет следующий посетитель, сначала найдите сохраненный файл и, если он существует, не выполняйте весь код в файле index.php. Базовым примером может быть

     if (file_exists ($ cacheFileName))
    {
    требуется $ cacheFileName;
    выход;
    }
    
    //Далее приводится остальная часть кода index.php
    //..
    
    //предполагая, что ваш выход буферизирован и содержится в $ output:
    эхо $ выход;
    
    $ cacheFileName = '/path/to/your/file.inc ';
    file_put_contents ($ cacheFileName, $ output);
    
  3. Набор cron-задания, которое будет удалено сохраненный файл кэша с диска каждый час или так часто, как вам нужно кому. Кроме того, в index.php на каждой странице проверьте, как давно был создан кэшированный файл, и создайте новый файл кэша, если он был длиннее, чем нужно. Задание cron проще настроить.

Однако, чтобы ответить на глубокий философский вопрос, сохранение сгенерированных выходных данных на диск в отдельных файлах, вероятно, является лучшим способом, если вы не хотите полагаться на решения кэширования третьей вечеринки. APC хорошо подходит для кэширования кода, который будет регенерировать страницы, когда это необходимо, и memcached, безусловно, перегружен, если мы говорим о небольшом (ish) приложении.

-121--4435150-

Для ваших конкретных способов, вы бы сделали это так:

MyModel.objects.values_list('column1', flat=True).distinct()

Но другие плакаты правильны, чтобы сказать, что вы не должны думать «как я пишу этот SQL в ORM». Когда вы узнали Python, происходящий из Java или C++ или что-то еще, вы вскоре научились выходить из мышления 'как мне написать этот код Java в Python', и просто сконцентрировались на решении проблемы с помощью Python. То же самое относится и к использованию ORM.

-121--3279185-

Работает следующий код.

#include <exception> 
#include <iostream> 

class A { 
public: 
    A(int i) { i_ = i; std::cout << "A " << i_ << " constructed" << std::endl; } 
    ~A() { std::cout << "A " << i_ << " destructed" << std::endl; } 
private: 
    int i_; 
}; 

void test() {
    A a1(1); 
    A a2(2); 
    throw std::exception(); 
} 

int main(void) { 
 try {
  test();
 } catch(...) {
 }
    return 0; 
} 
0
ответ дан 1 December 2019 в 17:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: