Имеется DLL C++ скомпилированная на MSVC. При динимической подгрузке DLL инициализируется фабрика и создает класс который используется дальше.
Пример описания возвращаемого класса на C++ MSVC:
class Test
{
virtual void Call(int t);
virtual void Call(wchar_t* t);
virtual void F(wchar_t* t);
virtual void Call(double t);
};
Теперь, когда я хочу использовать этот класс и использую C++ Builder, то для корректной работы мне необходимо переописать класс, изменив порядок всех overload методов.
Пример описания этого же класса C++ (C++ Builder):
class Test
{
virtual void Call(double t);
virtual void Call(wchar_t* t);
virtual void Call(int t);
virtual void F(wchar_t* t);
};
И собственно, точно так же мне необходимо менять местами методы в Delphi.
Пример описания на Delphi:
type
Test = class
procedure Call(t: Double); overload; virtual; abstract;
procedure Call(t: PChar); overload; virtual; abstract;
procedure Call(t: Integer); overload; virtual; abstract;
procedure F(t: PChar); overload; virtual; abstract;
end;
Почему это происходит? Какой из компиляторов производит данную оптимизацию и возможно ли как то ее избежать? Либо же заставить производить ее оба компилятора?
МSVС++ группирует виртуальные функции одного класса по именам функций. Порядок следования групп соответствует порядку первого появления какой-нибудь функции из группы в исходном файле. Затем внутри каждой группы порядок следования функций заменяется на обратный (по отношению к порядку объявления в исходном файле). Полученный в результате порядок - это и есть порядок в виртуальной таблице.
Именно это вы и наблюдаете в вашем случае. То есть сначала вы получаете две группы
virtual void Call(int t);
virtual void Call(wchar_t* t);
virtual void Call(double t);
virtual void F(wchar_t* t);
(именно в таком порядке следования групп), а затем порядок внутри каждой группы меняется на обратный
virtual void Call(double t);
virtual void Call(wchar_t* t);
virtual void Call(int t);
virtual void F(wchar_t* t);
Вот так будет выглядеть виртуальная таблица в MSVC++.
Таким образом пока вы не пользуетесь перегрузкой функций, функции в виртуальной таблице будут идти в порядке объявления. Но как только в вашем классе появляются функции с одинаковыми именами, начинается вот такое переупорядочение.
Разумеется, такая группировка выполняется только среди новых функций каждого отдельного класса. Если в классе-наследнике вы добавите функции с теми же именами, но с другими сигнатурами, то все новые функции в виртуальной таблице будут добавлены после функций предка. Но опять же, среди добавленных функций группировка и переупорядочение будут делаться по вышеописанным правилам.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Необходимо написать функции перевода вещественных и целых чисел в строку без функцийПервую функцию написал
У меня есть указатель на вектор std::vector*Как получить адрес элемента i этого вектора?
В Java, начиная с 8 версии, появилась новая вариация OutOfMemory error : Metaspace