Не вызывается деструктор у класса

199
26 июня 2017, 20:01

Доброго времени суток. Имеется класс, который изменяет кодировку консоли. Код:

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
class edit_locale
{
    int old_cin;
    int old_cout;
public:
   edit_locale(int);
   ~edit_locale();
};
int main()
{
    edit_locale(1251);
    std::cout << "Иван" << std::endl;
   return 0;
}

edit_locale::edit_locale(int cp)
{
   this->old_cin = GetConsoleCP();
   this->old_cout = GetConsoleOutputCP();
   SetConsoleCP(cp);
   SetConsoleOutputCP(cp);
}
edit_locale::~edit_locale()
{
   SetConsoleCP(this->old_cin);
   SetConsoleOutputCP(this->old_cout);
}

Проблема заключается в следующем: функция SetConsole срабатывает только в конструкторе, в main - функции изменений не происходит. И деструктор не вызывается. С чем это может быть связано? Спасибо.

Answer 1

Проблема в строчке

edit_locale(1251);

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

Пишите так:

edit_locale l(1251);
Answer 2

Попробуйте создать объект :)

int main()
{
    edit_locale el(1251);
    std::cout << "Иван" << std::endl;
    return 0;
}

Без этого в main() создается (и тут же, до вывода строки) уничтожается временный объект.

Чтоб было понятнее -

#include <iostream>
class test
{
public:
    test()  { std::cout << "ctor\n"; }
   ~test()  { std::cout << "dtor\n"; }
};
void f()
{
    test();
    std::cout << "in f\n";
}
void g()
{
    test t;
    std::cout << "in g\n";
}

int main()
{
    std::cout << "call f()\n";
    f();
    std::cout << "call g()\n";
    g();
}

Update

Можно обойтись и временным объектом - если поступить так:

#include <iostream>
#include <Windows.h>
class edit_locale
{
    int old_cin;
    int old_cout;
public:
    template<typename T>
        edit_locale(int,T f);
    ~edit_locale();
};
int main()
{
    edit_locale{1251,[](){
        std::cout << "Иван" << std::endl;
    }};
    return 0;
}

template<typename T>
edit_locale::edit_locale(int cp, T f)
{
    this->old_cin = GetConsoleCP();
    this->old_cout = GetConsoleOutputCP();
    SetConsoleCP(cp);
    SetConsoleOutputCP(cp);
    f();
};
edit_locale::~edit_locale()
{
    SetConsoleCP(this->old_cin);
    SetConsoleOutputCP(this->old_cout);
}

Кстати, мне всегда хотелось в C++ иметь возможность для всяких lock'ов и иже с ними писать не

{
    lock lk;
    // что-то делаем
}

а

lock{
    // что-то делаем
}

Так, по-моему, выглядит понятнее. С лямбдами имеем определенный суррогат...

READ ALSO
Вопрос на собеседовании про движок для карт [требует правки]

Вопрос на собеседовании про движок для карт [требует правки]

На собеседовании меня спросили про опыт работы программистом в авиационной сфереЯ сказал, что написал на Qt (С++) программу расчета траектории...

191
Drupal 7, JQuery и flexslider

Drupal 7, JQuery и flexslider

Главная проблема - не работает flexslider - поставил JQuery update, как советуют, но это не помогает

329
Как с помощью diff сравить 2 даты?

Как с помощью diff сравить 2 даты?

Как с помощью метода diff, правильно сравнить 2 даты?

300
Вертикальный текст в chart.js

Вертикальный текст в chart.js

Доброго времени сутокПерерыл документацию по chart

208