Разница в разметке памяти между вложенными классами и множественным наследованием в C ++? - PullRequest
3 голосов
/ 05 января 2011

Я пытаюсь понять, как COM определяет расположение своих объектов, чтобы клиент, который хочет использовать объект COM, знал, как это сделать.

Я читал, что COM-объект, который реализует несколько интерфейсов, может делать это по-разному, включая использование вложенных классов или множественное наследование.

Насколько я понимаю, оба метода должны были бы создавать одну и ту же схему памяти (соответствующую спецификации COM), чтобы клиент, который хочет использовать объект COM (например, в C), знал, как это сделать. *

Итак, мой конкретный вопрос: есть ли разница в расположении памяти для объектов c ++, реализованных с использованием множественного наследования по сравнению с вложенными классами.

А может кто-нибудь указать мне, где указана компоновка COM-объекта?

Ответы [ 4 ]

8 голосов
/ 06 января 2011

COM полностью не зависит от расположения памяти вашего объекта.Все, что ему нужно и нужно, - это таблица указателей на функции, когда он вызывает IUnknown::QueryInterface().Как вы реализуете это полностью зависит от вас.MFC использует вложенные классы, почти все, что использует встроенную поддержку множественного наследования в компиляторе C ++.То, как компилятор MSVC ++ реализует его, полностью совместимо с тем, что нужно COM.Это не случайно.Используйте стандартный код, который вы видите в книгах о COM, который показывает, как правильно реализовать IUnknown.

5 голосов
/ 06 января 2011

Единственная «раскладка», указанная в COM, - это vtable (таблица указателей виртуальных функций), связанная с каждым интерфейсом. Каждый интерфейс наследуется от IUnknown, поэтому любой интерфейс объекта, на который имеет указатель клиент, может вызвать QueryInterface для получения другого интерфейса для того же объекта.

Не существует обязательного макета для объектов. Действительно, вся идея объекта в COM сильно отличается от экземпляра класса в языке OO: единственный способ узнать, предоставляются ли два интерфейса одним и тем же объектом COM, - это вызвать QueryInterface для интерфейса IUnknown на обоих из них если и только если они возвращают один и тот же указатель интерфейса, они являются интерфейсами одного и того же объекта.

Это довольно гибкая идея:

  • возможно, например, иметь COM-объекты с загруженной в память только частью их внутреннего состояния: другие части их состояния могут быть лениво загружены / распределены при запросе дополнительных интерфейсов.
  • Состояние COM-объекта может быть распределено по нескольким несмежным областям памяти.
1 голос
/ 05 января 2011

Я не верю, что один COM-интерфейс может иметь множественное наследование, но класс может реализовывать несколько интерфейсов через множественное наследование. Таким образом, компоновка множественного наследования не имеет значения - каждый интерфейс будет иметь уникальную компоновку, и компилятор должен предоставить указатель на правильную компоновку.

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

Вы обнаружите удивительный факт, если реализуете несколько интерфейсов через множественное наследование. Когда вы приведете указатель на ваш объект класса из одного интерфейса в другой, адрес изменится! Это потому, что разные интерфейсы (vtables) должны соответствовать объявлению интерфейса, поэтому должны быть разные макеты. Все эти макеты содержатся в одном и том же объекте, но компилятор выполняет манипуляции с указателями при приведении к нужному подмножеству.

0 голосов
/ 05 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...