Как множественное наследование C++ реализовано?

Я использовал этот, и он прекрасно работает для меня:

<%= link_to(line_items_path(product_id: product),
    method: :put,
    class: 'btn btn-success') do %>
    <%= content_tag('i', nil, class: 'icon-search icon-white') %> Add To Cart
<% end %>

Надеюсь, это поможет

21
задан 16 June 2009 в 19:29
поделиться

7 ответов

Следующая статья создателя C ++ описывает возможную реализацию множественного наследования:

Множественное наследование для C ++ - Бьярн Страуструп

10
ответ дан 29 November 2019 в 21:49
поделиться

And then, if I do a cast:

SecondBase base = (SecondBase *) object_with_base1_and_base2_parents;

The compiler must consider whether to alter or not the original pointer. Similar tricky things with virtuals.

With non-virutal inheritance this is less tricky than you might think - at the point where the cast is compiled, the compiler knows the exact layout of the derived class (after all, the compiler did the layout). Usually all that happens is a fixed offset (which may be zero for one of the base classes) is added/subtracted from the derived class pointer.

With virutal inheritance it is maybe a bit more complex - it may involve grabbing an offset from a vtbl (or similar).

Stan Lippman's book, "Inside the C++ Object Model" has very good descriptions of how this stuff might (and often actually does) work.

5
ответ дан 29 November 2019 в 21:49
поделиться

Была эта довольно старая статья MSDN о том, как это было реализовано в VC ++.

5
ответ дан 29 November 2019 в 21:49
поделиться

This is an interesting issue that really isn't C++ specific. Things get more complex also when you have a language with multiple dispatch as well as multiple inheritance (e.g. CLOS).

People have already noted that there are different ways to approach the problem. You might find reading a bit about Meta-Object Protocols (MOPs) interesting in this context...

1
ответ дан 29 November 2019 в 21:49
поделиться

Родители расположены в том порядке, в котором они указаны:

class Derived : A, B {} // A comes first, then B

class Derived : B, A {} // B comes first, then A

Второй случай обрабатывается в зависимости от компилятора. . Один из распространенных методов - использование указателей, размер которых превышает размер указателя платформы, для хранения дополнительных данных.

1
ответ дан 29 November 2019 в 21:49
поделиться

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

0
ответ дан 29 November 2019 в 21:49
поделиться

Я провел простой эксперимент:

class BaseA { int a; };
class BaseB { int b; };
class Descendant : public BaseA, BaseB {};
int main() {
        Descendant d;
        BaseB * b = (BaseB*) &d;
        Descendant *d2 = (Descendant *) b;
        printf("Descendant: %p, casted BaseB: %p, casted back Descendant: %p\n", &d, b, d2);
}

Результат:

Descendant: 0xbfc0e3e0, casted BaseB: 0xbfc0e3e4, casted back Descendant: 0xbfc0e3e0

Хорошо осознавать, что статическое приведение не всегда означает «изменить тип, не затрагивая содержимое». (Ну, когда типы данных не подходят друг другу, тогда будет также вмешательство в контент, но это другая ситуация, IMO).

0
ответ дан 29 November 2019 в 21:49
поделиться
Другие вопросы по тегам:

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