LINUX.ORG.RU

C++, BOOST_FOREACH и ссылки.


1

1

В std::cout передаются какие-то левые указатели, не могу понять почему.

struct Aaa
{
	typedef std::vector < std::string > Vec;
	Aaa()
	{
		m_vec.push_back( "sobaka" );
		m_vec.push_back( "mendeley" );
	}
////
	Vec m_vec;
};

struct Bbb
{
	Aaa& get(){ return m_aaa; }
////
	Aaa m_aaa;
};


/////////// main() ////////
...
Bbb b_obj;
Aaa &ref_a = b_obj.get();
BOOST_FOREACH( const Aaa::Vec::value_type &_val, ref_a.m_vec )
{
	std::cout << _val << "\n";
}
Ответ на: комментарий от dzidzitop

Меня больше конструкторы интересовали.

А в C++11 исключения в деструкторах ведут к внезапному окончанию жизни программы.

Это не (совсем) так. Просто все деструкторы в С++ теперь неявно обьявлены как noexcept. Никто не запрещает обьявить деструктор как noexcept(false). А дальше всё как в С++98.

Плюс две мелкие придирки:

Во первых, не «внезапное окончание жизни программы, а вызов std::terminate. На который можно повесить свой обработчик.

Во вторых, само по себе исключение в деструкторе ни к чему не приводит (если оно обрабатывается внутри).

Но меня больше конструкторы интересовали.

нужно акуратно контролировать что нужно самостоятельно деструктить, если кидаются исключения

Зачем?

Также нужно выпасывать какие функцыи что вызывает конструктор могут кинуть исключения.

Зачем?

Багов можно наловить без проблем.

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

Но я что-то не увидел альтернативы. Неужели двухфазная инициализация? И чем это лучше? Все проблемы остаются (точно так же нужно „нужно выпасывать какие функцыи что вызывает конструктор могут кинуть исключения“ если мы не хотим вообще бросать исключения) плюс теперь у нас обьект ещё может оказаться в непроинициализированном состоянии. В определённых случаях она нужна, но далеко не везде.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

про noexcept(false) не знал, спасібо. Остальное подразумевалось.

про исключения в конструкторе: - то, что было аллоціровано - не удаляется автоматически - деструктор обьекта не вызывается

struct Foo
{
    int *x;

    Foo()
    {
         x = new int(0);
         throw "whatever";
         // x is not deleted.
         // destructor is not invoked
    }

    ~Foo()
    {
        delete x;
    }
}
anonymous
()
Ответ на: комментарий от DarkEld3r

Неужели двухфазная инициализация?

Скорее нет. Просто нужно внимательно кодить + гонять детекторы memory leaks.

И чем это лучше?

Лучше только тем, что деструктор обьекта будет вызван.

dzidzitop

anonymous
()
Ответ на: комментарий от anonymous

про исключения в конструкторе: - то, что было аллоціровано - не удаляется автоматически - деструктор обьекта не вызывается

std::unique_ptr

oh-la-la
()
Ответ на: комментарий от anonymous

про исключения в конструкторе: - то, что было аллоціровано - не удаляется автоматически - деструктор обьекта не вызывается

Ясное дело. Поэтому писать надо так:

struct Foo
{
    std::unique_ptr<int> x;

    Foo()
        : x(new int(0))
    {
         throw "whatever";
         // x is deleted now.
    }

    ~Foo()
    {}
}

DarkEld3r ★★★★★
()
Ответ на: комментарий от anonymous

Лучше только тем, что деструктор обьекта будет вызван.

Если писать правильно (RAII наше всё), то это просто не потребуется.

DarkEld3r ★★★★★
()
Ответ на: комментарий от DarkEld3r

угу, unique_ptr помогает.

dzidzitop

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.