LINUX.ORG.RU

std::mem_fun(&Class::method)(obj); и нефиг извращаться.

const86 ★★★★★ ()
Ответ на: комментарий от const86

вот в чем минус с++-, это что большинство программистов какие-то шуганые. «т-с-с, этого нельзя хотеть!»

gavv ()
Ответ на: комментарий от gavv

ну-ну

посмотрим, что ты скажешь, если микрософт сломает твою программу в следующей версии компилятора (а они имеют полное право)

с другой стороны, если речь вести о программистах, а не языке, то мне кажется в плюсах создаются излишние абстракции на пустом месте; я бы хотел иметь описание реализации виртуальной функции в таком (явном) виде, чтобы программист мог им воспользоваться (и это был бы демократизм языка)

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

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

А что тебе сейчас мешает воспользоваться виртуальной функцией (если она не чисто виртуальная), узнать ее описание и даже (о, ужас!) реализацию, если есть исходники?

LamerOk ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

чуть подробнее:

в стандарте должен быть прописан интерфейс vtbl, а реализация языка должна предоставлять реализацию интерфейса;

причем эта реализация должна не быть спрятана в недрах компилятора, а выражена *кодом*;

программист должен иметь возможность юзать не только интерфейс, но и особенности реализации;

для разных компиляторов это будут *разные* особенности, но как обычно они будут выбираться во время компиляции (аналогично #ifdef, только на шаблонах)

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от LamerOk

> А что тебе сейчас мешает воспользоваться виртуальной функцией (если она не чисто виртуальная), узнать ее описание и даже (о, ужас!) реализацию, если есть исходники?

Очевидно, то, что я не могу автоматизировать действие «изменилась реализация — мои исходники отказались компилироваться».

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от LamerOk

> А что тебе сейчас мешает воспользоваться виртуальной функцией (если она не чисто виртуальная),

@#$@!#$@ только щас дошло, что ты меня не понял

говоря о «реализации виртуальной функции», я имею в виду vtbl, а не код, написанный прикладным программистом

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от madcore

> Подробнее, для чего?

простейший пример: у нашей иерархии классов *ровно одна* виртуальная функция (для визиторов :-) и мы ее (а не &vtbl) храним прямо в объекте, устранив необходимость одного разрешения адреса

или приделать двойную диспетчеризацию

а еще у gavv надо спросить

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

> для разных компиляторов это будут *разные* особенности

Но они должны быть выражены в стандарте, а программист должен заниматься #ifdef'ом? Т.е. эскпешна в прошлом разе тебе мало?

LamerOk ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

> я не могу автоматизировать действие «изменилась реализация — мои исходники отказались компилироваться».

Какая трагедия. Программисты всего мира выражают свою солидарность с тобой в эту трудную для тебя минуту.

LamerOk ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

Ага! Так тебе нужно описание _механизма_ виртуальных функций. )))

А зачем? Чем тебя структуры с указателями на не устраивают?

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

А зачем? Чем тебя структуры с указателями на не устраивают?

Вот и gусть будет конструкция vtableof(someclass), «возвращающая» (в том смысле, как typeof) что-то наподобите такого типа:

union someclass_vtable
{
  struct
  {
    int do_smth_0(someclass *, int arg);
    void do_smth_1(const someclass *, iostream & arg);
    size_t do_smth_2(someclass *);
  };
  memfunc_t memfunctions[3]; // typedef void (memfunc*) ();
};
legolegs ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

в стандарте должен быть прописан интерфейс vtbl, а реализация языка должна предоставлять реализацию интерфейса;

Куда только грязные волосатые руки быдлокодеров не лезут. Ну нет там такого. Детали особенностей реализации ООП скрыты. Плачь горькими слезами.

З.Ы. ИМХО надо разгрести в С++ то, что есть, а не городить новые странные сущности.

pathfinder ★★★ ()
Ответ на: комментарий от pathfinder

> Детали особенностей реализации ООП скрыты.

Необходимые для тюнинга и расширения детали особенностей реализации ООП скрыты. // FIXED

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от LamerOk

> Но они должны быть выражены в стандарте, а программист должен заниматься #ifdef'ом?

Прочти несколько раз что я писал и попробуй понять.

Т.е. эскпешна в прошлом разе тебе мало?

Ты и в этот раз собираешься применить свой коронный аргумент «ну ты конечно сам понимаешь, что»?

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от legolegs

> конструкция vtableof(someclass)

но хотелось бы покруче: стандарт должен указывать интерфейс (куча функций и инвариантов)

реализаторы (одного компилятора) могут ввести vtableof(someclass) и реализовать этот интерфейс через него

реализаторы другого компилятора могут реализовать через virtual_table<someclass> или вообще *совсем* по-другому

www_linux_org_ru ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

> Ты и в этот раз собираешься применить свой коронный аргумент

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

LamerOk ★★★★★ ()
Ответ на: комментарий от www_linux_org_ru

> реализаторы (одного компилятора) могут

реализаторы другого компилятора могут


Ты сам можешь. Без всяких плюсов, на чистом С. Чего ты до компиляторов и стандарта докопался?

LamerOk ★★★★★ ()
Ответ на: комментарий от gavv

> вот в чем минус с++-, это что большинство программистов какие-то шуганые. «т-с-с, этого нельзя хотеть!»

Я не запрещал ничего хотеть, а показал более прямой путь. Есть и более «низкоуровневый» путь: просто использовать тип void (Class::*)(). Зачем приводить его к void (*)(Class*)? Нешуганые программисты имеют полное право хотеть кастовать указатель на метод к указателю на функцию, void* к int, std::list<double> к std::string и даже делить на ноль, если они ясно понимают, что, почему и при каких условиях они получат в результате, а не только что они хотели бы получить.

const86 ★★★★★ ()
Ответ на: комментарий от const86

нет, нет, я же не в обиду
получить мне надо (эффективное) взаимодействие классов на с++ и генерируемого в рантайме кода, не завязываясь на реализации vtbl, для msvc есть, например, FastDelegate, но в gcc решение намного красивее

gavv ()
Ответ на: комментарий от const86

>Зачем приводить его к void (*)(Class*)
потому что вызов указателя на метод это, грубо говоря,
if (ptr[0]) (ptr[0])(obj)
else (obj->vtbl[ptr[1]])(obj)
а в моем случае эта (микро)оптимизация существенна

gavv ()
Ответ на: комментарий от gavv

> потому что вызов указателя на метод это, грубо говоря,

Так этот if делается в мозгах у компилятора же, а не в рантайме. Или речь не о той оптимизации?

const86 ★★★★★ ()
Ответ на: комментарий от const86

если вызвать указатель на метод и посмотреть ассемблерный код, то там будет проверка, потому что в указателе либо адрес, _либо смещение в vtbl
у меня же на момент генерации кода все адреса уже известны, и есть смысл не использовать виртуальность, а вкомпилировать константы. и при этом нужен интерфейс к обычным с++-ным классам

gavv ()
Ответ на: комментарий от gavv

в общем, пока я тут распрастранялся, я уже использовал на прямую vtbl msvc :)

gavv ()
Ответ на: комментарий от gavv

>а в моем случае эта (микро)оптимизация существенна

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

Завязывайте со своими нанооптимизациями.

pathfinder ★★★ ()
Ответ на: комментарий от pathfinder

Если что-то действительно существенно, то всегда можно и без классического ООП обойтись. Используйте что-то вроде void foobar(MyObject* __this,...)

pathfinder ★★★ ()
Ответ на: комментарий от gavv

> если вызвать указатель на метод и посмотреть ассемблерный код, то там будет проверка, потому что в указателе либо адрес, _либо смещение в vtbl

Да, допёрло где я ошибся. Теперь хоть понятно, что хотелось получить, с этого надо было начинать ;)

И что, эта проверка правда заметна на фоне выполнения самого метода? Надо подумать, можно ли её как-то обойти без грязных хаков.

const86 ★★★★★ ()
Ответ на: комментарий от const86

да это грязный хак только в msvc
ну, это уже мои интимные проблемы, но речь об геттерах/сеттерах, которые некоторые на с++, некоторые должны сгенериться, а вызываются они для каждого свойства каждого объекта 3д-рендерера

gavv ()
Ответ на: комментарий от gavv

вменяемое решение - просто не делать их функциями, но мне не подходит
вообще все это звучит слишком пафосно

gavv ()
Ответ на: комментарий от pathfinder

>Используйте что-то вроде void foobar(MyObject* __this,...)
можно и так, кто же спорит

gavv ()
Ответ на: комментарий от gavv

>если вызвать указатель на метод и посмотреть ассемблерный код, то там будет проверка, потому что в указателе либо адрес, _либо смещение в vtbl

Покажи-ка? Не понял. И как различаются адрес и смещение(в указателе?)?

madcore ★★★★★ ()
Ответ на: комментарий от madcore

указатель на метод - пара адрес-индекс. если адрес == 1, то берется индекс.
выдранный кусок (с -O3):

	movl	S1::a(), %edx
	movl	%eax, %ecx
	movl	%edx, %eax
	testb	$1, %al
	je	.L5
	movl	(%ecx), %eax
	movl	S1::a()-1(%eax), %edx
.L5:
	movl	%ecx, (%esp)
	call	*%edx
после таких примеров меня тут совсем за красноглазого сочтут :)

gavv ()
Ответ на: комментарий от gavv

>выдранный кусок (с -O3):

Ну да. Остается ТС пожелать сладких часов дебага.

pathfinder ★★★ ()
Ответ на: комментарий от gavv

>указатель на метод - пара адрес-индекс. если адрес == 1,

«testb $1, %al» - проверка на четность.

то берется индекс.


Индекс относительно какого адреса?

выдранный кусок (с -O3):


Из чего он получается? Здается, там проверка совсем не связанная с вызовом метода, просто оптимизатор так смикшировал код.

madcore ★★★★★ ()
Ответ на: комментарий от gavv

>речь об геттерах/сеттерах, которые некоторые на с++, некоторые должны сгенериться, а вызываются они для каждого свойства каждого объекта 3д-рендерера

ну и зачем здесь виртуальные методы ? Зачем там методы вообще ?

программы делятся на те, которые тешат чсв и те, которые выполняются на машине. 3д рендеры для чсв не нужны.

sleepy ()

HINT:

В хидерах для директХ есть куча буков, которые позволяют юзать этот самый ДиректХ из чистого С.

Суть подхода такова - по указателю на интерфейс, получаем указатель на vtbl, по индексу функции в vtbl получаем адрес, с которого начинается код виртуальной функции.

Полученный адрес можно заюзать как каллбек, не забыв передать вручную указатель на this.

Этот метод будет работать под оффтопом всегда, поскольку фиг они откажуться от совместимости со старым софтом!

AF ★★★ ()
Ответ на: комментарий от AF

К твоему сведению DirectX оформлен в виде COM-интерфейсов. А COM как бы документирован и от языка не зависит.

anonymous ()
Ответ на: комментарий от anonymous

>А COM как бы документирован и от языка не зависит.

Угу, и че там написанно про реализцию интерфейса?

AF ★★★ ()
Ответ на: комментарий от AF

Тебе сюда скопи-пастить всю спецификацию?

anonymous ()
Ответ на: комментарий от anonymous

Если ты не в состоянии найти в ней ответ на поставленный вопрос, то другого пути как бы и нет:)

AF ★★★ ()
Ответ на: комментарий от AF

Свой вопрос сформулируй для начала.

anonymous ()
Ответ на: комментарий от anonymous

> Свой вопрос сформулируй для начала.

Ок, принято.

Меня интересует, как должен выглядеть интерфейс в бинарном виде, чтобы он соответствовал СОМ?

Чего общего между указателем на СОМ интерфейс и указателем на базовый абстрактный класс в С++?

Ну и на закуску риторический вопрос - как далеко будет послан микрософт , если они изменят в своем новом С++ компилере бинарное представление тех самых данных, на которые ссылается указатель на базовый абстрактный класс?

AF ★★★ ()
Ответ на: комментарий от AF

> Чего общего между указателем на СОМ интерфейс и указателем на базовый абстрактный класс в С++?

В общем случае ничего общего нет т.к. бинарная структура COM-интерфейса задокументирована, а бинарная структура абстрактного класса в языке C++ не документирована.

В частном случае конкретная реализация С++ при определенных ограничениях может генерировать бинарную структуру абстрактного класса совместимую с COM.

anonymous ()
Ответ на: комментарий от AF

> Ну и на закуску риторический вопрос - как далеко будет послан микрософт , если они изменят в своем новом С++ компилере бинарное представление тех самых данных, на которые ссылается указатель на базовый абстрактный класс?

Бинарное представление C++ объектов в реализации компилятора от Microsoft документировано.

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.