доброго времени суток!
вот цитата из "Эффективное использование С++" Скотта Мэйерса:
Но имейте в виду, что в общем случае оптимизация EBO применяется только для одиночного наследования. Действующие в С++ правила размещения объектов в памяти обычно делают невозможной такую оптимизацию, если производный класс имеет более одного базового.
Тэг CODE не предназначен для цитирования!!! И делайте предпросмотр.
— Кодт
к сожалению, автор только ссылается на некие правила С++ и не дает никаких комментариев по этому поводу... за сим обращаюсь к Вам — почему в случае impl_0, impl_1, impl_2 и impl_4 компилятор реализовал EBO, а в случае с impl_3 — нет? указывать на то, что в impl_3 empty_base_0 и empty_base_1 следуют друг за другом не нужно. нужно объяснить почему этот факт мешает компилятору реализовать EBO
class empty_base_0
{ };
class empty_base_1
{ };
class storage
{ int i; };
class impl_0 : public empty_base_0
{ int g; };
class impl_1 : public empty_base_0, public storage
{ };
class impl_2 : public empty_base_0, public storage
{ int g; };
class impl_3 : public empty_base_0, public empty_base_1, public storage
{ int g; };
class impl_4 : public empty_base_0, public storage, public empty_base_1
{ int g; };
int _tmain(int argc, _TCHAR* argv[])
{
int iSize = 0;
iSize = sizeof(impl_0); // 4
iSize = sizeof(impl_1); // 4
iSize = sizeof(impl_2); // 8
iSize = sizeof(impl_3); // 12
iSize = sizeof(impl_4); // 8return 0;
}
Аноним 691:
А>вот цитата из "Эффективное использование С++" Скотта Мэйерса: А>
Но имейте в виду, что в общем случае оптимизация EBO применяется только для одиночного наследования. Действующие в С++ правила размещения объектов в памяти обычно делают невозможной такую оптимизацию, если производный класс имеет более одного базового.
к сожалению, автор только ссылается на некие правила С++ и не дает никаких комментариев по этому поводу...
Возможно, это какие-то неформальные правила Я как-то пытался найти ответ на схожий вопрос: из какого нормативного текста стандарта следует, что два подобъекта, имеющие один и тот же тип и принадлежащие одному и тому же most derived объекту, должны располагаться по разным адресам. Мои поиски так и не увенчались успехом.
#include <iostream>
struct B
{
B *ptr() { return this; }
};
struct D : B
{
B b;
};
int main()
{
D d;
std::cout << (d.ptr() == d.b.ptr()) << std::endl;
}
Может ли равенство d.ptr() == d.b.ptr() быть истинным? Согласно примечанию в 10/5, не может, но примечания не являются нормативными, и разработчики компиляторов вправе их игнорировать. В данном случае VC++ 8.0 и Intel C++ 11.0 располагают data member и базовый подобъект по одному адресу.
Re: empty base optimization и множественное наследование
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re: empty base optimization и множественное наследование
Здравствуйте, Аноним, Вы писали:
А>доброго времени суток!
Вроде первый из предков "настоящий". МФЦ "допускает" множественное наследование если первый Object а второй свой. этим impl_3 отличается от impl_4 . Я тут дополнил и запустил
Здравствуйте, Николай Ивченков, Вы писали:
НИ>Возможно, это какие-то неформальные правила Я как-то пытался найти ответ на схожий вопрос: из какого нормативного текста стандарта следует, что два подобъекта, имеющие один и тот же тип и принадлежащие одному и тому же most derived объекту, должны располагаться по разным адресам. Мои поиски так и не увенчались успехом.
НИ>
#include <iostream>
НИ>struct B
НИ>{
НИ> B *ptr() { return this; }
НИ>};
НИ>struct D : B
НИ>{
НИ> B b;
НИ>};
НИ>int main()
НИ>{
НИ> D d;
НИ> std::cout << (d.ptr() == d.b.ptr()) << std::endl;
НИ>}
НИ>Может ли равенство d.ptr() == d.b.ptr() быть истинным? Согласно примечанию в 10/5, не может, но примечания не являются нормативными, и разработчики компиляторов вправе их игнорировать. В данном случае VC++ 8.0 и Intel C++ 11.0 располагают data member и базовый подобъект по одному адресу.
спасибо за ответ! но мне кажется, в Вашем случае все объяснимо:
struct B
{
B *ptr() { return this; }
};
struct D : B // здесь компилятор реализует EBO
{
B b; // адрес b совпадает с адресом наследуемого B
};
// sizeof(D) == 1, и Derived.ptr() == Derived.b.ptr()
struct B
{
B *ptr() { return this; }
};
struct D : B // здесь компилятор реализует EBO
{
B b; // адрес b совпадает с адресом наследуемого Bchar m_c;
};
// sizeof(D) == 2, и Derived.ptr() == Derived.b.ptr()
struct B
{
B *ptr() { return this; }
};
struct D : B // здесь компилятор реализует EBO
{
char m_c;
B b; // адрес b не совпадает с адресом наследуемого B
};
// sizeof(D) == 2, и Derived.ptr() != Derived.b.ptr()
вот что у меня получилось в процессе тестирования:
Здравствуйте, Faust, Вы писали:
F>Здравствуйте, Programador, Вы писали:
P>>А ЕБО что? Законный прием или опция оптимизации? F>вроде как, законный прием... F>вот тест на MSVC 8: F>
F> empty_base_0 e0;
F> e0 = i0; // нет ошибки и нет кода!!!
F>
Пробовал на g++ ему привидение нужно. Причем приведение в краткой форме сейчас небезопасны
int eee;
(empty_base_0&)eee=e0; // Ок
только static_cast, раньше указатели неправильные только через void* приводились
А длина разная потому что МС первый взял и сразу до 1 длину расширил. А g++ на ум взял
Re[2]: empty base optimization и множественное наследование
Здравствуйте, Николай Ивченков, Вы писали:
НИ>Возможно, это какие-то неформальные правила Я как-то пытался найти ответ на схожий вопрос: из какого нормативного текста стандарта следует, что два подобъекта, имеющие один и тот же тип и принадлежащие одному и тому же most derived объекту, должны располагаться по разным адресам. Мои поиски так и не увенчались успехом.
Из соображений идентичности.
Подобъекты из разных веток наследования не идентичны. А в С++ идентичность определяется адресом. Следовательно... правильно!
А вот к разнотипным объектам отношение идентичности неприменимо, поэтому они могут как угодно накладываться друг на друга, вплоть до совпадения адресов.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[3]: empty base optimization и множественное наследование
Кодт:
НИ>>Возможно, это какие-то неформальные правила Я как-то пытался найти ответ на схожий вопрос: из какого нормативного текста стандарта следует, что два подобъекта, имеющие один и тот же тип и принадлежащие одному и тому же most derived объекту, должны располагаться по разным адресам. Мои поиски так и не увенчались успехом.
К>Из соображений идентичности. К>Подобъекты из разных веток наследования не идентичны. А в С++ идентичность определяется адресом. Следовательно... правильно!