Re[3]: [MSVC] Инициализация членов класса
От: IROV..  
Дата: 18.04.11 17:47
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, IROV.., Вы писали:


IRO>>Писать


IRO>>: bar(this->foo)


IRO>>Тогда получишь варнинг


A>очевидно это не тот варнинг

Тот-тот, он как раз и предупреждает программиста о том что — по мнению компилятора, мы здесь используем непроинициализированый указатель(this), и добром это не кончеться.

A>еще можно написать "bar(!@#$%^)" и получить error

как щас модно говорить в геймерских кругах, "удали студию"

2.
У меня в кодестайле прописано, что в конструкторах нельзя выполнять функции.
Если нужно пишем — initialize, если до, значит нужен какойто менеджер.
я не волшебник, я только учусь!
Re[9]: [MSVC] Инициализация членов класса
От: Хвост  
Дата: 18.04.11 18:49
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Ну я именно это и хотел сказать, что дело не в порядке, а вообще в том что мы используем(разыменовываем) неготовый указатель.

никакого разыменования (использования) там нет, вариант с this-> ты придумал сам.
People write code, programming languages don't.
Re[10]: [MSVC] Инициализация членов класса
От: IROV..  
Дата: 18.04.11 19:19
Оценка:
Здравствуйте, Хвост, Вы писали:

Х>Здравствуйте, IROV.., Вы писали:


IRO>>Ну я именно это и хотел сказать, что дело не в порядке, а вообще в том что мы используем(разыменовываем) неготовый указатель.

Х>никакого разыменования (использования) там нет, вариант с this-> ты придумал сам.

9.3.2
я не волшебник, я только учусь!
Re[10]: [MSVC] Инициализация членов класса
От: wander  
Дата: 18.04.11 19:36
Оценка:
Здравствуйте, Хвост, Вы писали:

Х>Здравствуйте, IROV.., Вы писали:


IRO>>Ну я именно это и хотел сказать, что дело не в порядке, а вообще в том что мы используем(разыменовываем) неготовый указатель.

Х>никакого разыменования (использования) там нет, вариант с this-> ты придумал сам.
Как это нет??!
struct Bar
{
    Bar(Foo & f)
    {
        //...
        f.load(); //а это что?
    }
};
Re: [MSVC] Инициализация членов класса
От: martin Беларусь  
Дата: 18.04.11 19:38
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Сейчас где-то час потратил на то чтобы найти баг в следующем коде:


A>
A>#include <vector>

A>struct Foo
A>{
A>    Foo() {}

A>    void load(/*...*/)
A>    {
A>        v.clear(); // тут возникает assert "итераторы несовместимы"
A>    }

A>    std::vector<int> v;
A>};

A>struct Bar
A>{
A>    Bar(Foo& f)
A>    {
A>        //...
A>        f.load(/*...*/);
A>    }
A>};

A>struct Holder
A>{
A>    Holder()
A>        : bar(foo)
A>        , foo()
A>    {}

A>    Bar bar;
A>    Foo foo;
A>};

A>int main()
A>{
A>    Holder h;
A>}
A>


A>Как такого избежать?


Посмотри в сторону boost::base_from_member.
Re[11]: [MSVC] Инициализация членов класса
От: Хвост  
Дата: 18.04.11 19:42
Оценка:
Здравствуйте, wander, Вы писали:

W>Как это нет??!


я вообще не об этом говорю, я говорю о том что использование проинициализированных полей объекта до полной инициализации самого объекта не является UB, как в этом пытается убедить нас IROV.
People write code, programming languages don't.
Re[11]: [MSVC] Инициализация членов класса
От: IROV..  
Дата: 18.04.11 19:44
Оценка:
Здравствуйте, wander, Вы писали:

W>
W>struct Bar
W>{
W>    Bar(Foo & f)
W>    {
W>        //...
W>        f.load(); //а это что?
W>    }
W>};
W>


    Holder()
        : bar(foo) //а это что???


я не волшебник, я только учусь!
Re[11]: [MSVC] Инициализация членов класса
От: IROV..  
Дата: 18.04.11 19:45
Оценка:
Здравствуйте, wander, Вы писали:

W>Как это нет??!

W>
W>struct Bar
W>{
W>    Bar(Foo & f)
W>    {
W>        //...
W>        f.load(); //а это что?
W>    }
W>};
W>

Кстати тут разыменования нету

void load(/*...*/)
    {
        v.clear(); // оно в дебрях там
    }


я не волшебник, я только учусь!
Re[12]: [MSVC] Инициализация членов класса
От: wander  
Дата: 18.04.11 19:46
Оценка:
Здравствуйте, Хвост, Вы писали:

Х>Здравствуйте, wander, Вы писали:


W>>Как это нет??!


Х>я вообще не об этом говорю, я говорю о том что использование проинициализированных полей объекта до полной инициализации самого объекта не является UB, как в этом пытается убедить нас IROV.

Так тут как раз используется непроинициализированное. Что касается выделенного, мне не кажется, что он в этом пытается нас убедить.
Re[12]: [MSVC] Инициализация членов класса
От: wander  
Дата: 18.04.11 19:50
Оценка:
Здравствуйте, IROV.., Вы писали:

IRO>Здравствуйте, wander, Вы писали:


IRO>Кстати тут разыменования нету


Зато ссылка есть. Я выделил использование.

IRO>

Re[2]: [MSVC] Инициализация членов класса
От: Abyx Россия  
Дата: 18.04.11 20:08
Оценка:
Здравствуйте, martin, Вы писали:

M>Посмотри в сторону boost::base_from_member.


посмотрел и не понял что вы хотите предложить.
In Zen We Trust
Re[3]: [MSVC] Инициализация членов класса
От: martin Беларусь  
Дата: 18.04.11 20:50
Оценка:
Здравствуйте, Abyx, Вы писали:

A>Здравствуйте, martin, Вы писали:


M>>Посмотри в сторону boost::base_from_member.


A>посмотрел и не понял что вы хотите предложить.


Насколько я понимаю, в вашем примере проблема в том что bar пытается использовать объект foo который еще не создан. Проблему конечно можно избежать поменяв местами объявления членов bar и foo класса Holder. Тогда все будет ок. Но в будущем нельзя гарантировать что кто-нибудь их опять не поменяет случайно местами. Самое правильное, на мой взгляд, это сделать гарантированный вызов конструктора foo перед вызовом конструктора bar. Этого можно добиться с использованием наследования.

struct HolderBase 
{
   Foo foo;
};

struct Holder : protected HolderBase
{
    Holder()
        : bar(foo)
    {}

    Bar bar;
};


Это конечно не совсем Base-from-Member, но близко к нему.
Re: [MSVC] Инициализация членов класса
От: Alexander G Украина  
Дата: 20.04.11 10:34
Оценка: :)
Здравствуйте, Abyx, Вы писали:

A>...


A>Как такого избежать?


  • придерживаться Naming convention, который отличает data members от всего остального.

    struct Holder
    {
        Holder()
            : bar_(foo_) // выглядит подозрительно, необходимо проверить конструктор bar_.
            , foo_()
        {}
    
        Bar bar_;
        Foo foo_;
    };


  • стремиться хранить по указателю любые нетривиальные классы. это полезно ещё тем, что позволяет избежать лишних зависимостей (как в pimpl).

    struct Holder
    {
        Holder();
        scoped_ptr<Bar> bar_;
        scoped_ptr<Foo> foo_;
    };
    
    Holder::Holder()
    {
        bar_.reset(new Bar(*foo_)); // ошибка очевидна.
        foo_.reset(new Foo()); 
    }
  • Русский военный корабль идёт ко дну!
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.