LINUX.ORG.RU

Ответ на: комментарий от waker

метод привязан к типу объекта (классу)

в общем случае это просто вранье.

в том случае, где метод привязан к типу объекта, ответом будет «ну и чо? ты щас жопу с пальцем зачем сравнил?». допустим, что в твоем мире метод привязан к типу получателя. в любом случае в конце диспетчеризации вызовется метод, привязанный к типу объекта. ты путаешь вход и выход данные диспетчера? зачем сравниваешь (или не сравниваешь, кто тебя разберет) методы (выход) и сообщения (вход)?

итого: либо предлагаю вернуться к изначальному вопросу, либо сужаю и повторяю вопрос для этого твоего частного случая «метод привязан к типу объекта (классу)»: в любом случае есть диспетчер, получающий на входе сообщение и возвращающий на выходе метод, привязанный к типу получателя, так чем тебе подсмотр указателя метода в таблице не обработка сообщения? выбирай.

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

до аргумента разовьешь или тренируешься набрасывать? :)

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

In computer science, dynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time.

Ты ведь без труда найдёшь принципиальное несоответствие виртуальных методов крестов этому определению?

Минутка искромётного юмора: кто, кстати, говорил, что нельзя дёрнуть произвольный метод указателя на любую фигню? Можно:

#include <iostream>
using namespace std;

struct A {
  virtual void foo() {
    cout<<"A::foo\n";
  }
  virtual void bar() {
    cout<<"A::bar\n";
  }
};

struct B {
  virtual void foo() {
    cout<<"B::foo\n";
  }
  virtual void bar() {
    cout<<"B::bar\n";
  }
};

int main(int, char**) {
  A a;
  cout<<"Calling foo:\n";
  reinterpret_cast<B*>(&a)->foo();
  cout<<"Ok\n";
}

...правда не всегда:

#include <iostream>
using namespace std;

struct A {
  virtual void foo() {
    cout<<"A::foo\n";
  }
  virtual void bar() {
    cout<<"A::bar\n";
  }
};

// The only difference is in the definition order 
struct B {
  virtual void bar() {
    cout<<"B::bar\n";
  }
  virtual void foo() {
    cout<<"B::foo\n";
  }
};

int main(int, char**) {
  A a;
  cout<<"Calling foo:\n";
  reinterpret_cast<B*>(&a)->foo();
  cout<<"Too bad\n";
}
fmdw
()
Ответ на: комментарий от t184256

в том случае, где метод привязан к типу объекта, ответом будет «ну и чо? ты щас жопу с пальцем зачем сравнил?».

именно. как в крестах, например.

так чем тебе подсмотр указателя метода в таблице не обработка сообщения?

тем, что без знания типа компилятор не знает по какому индексу искать указатель на метод в vtbl, и выдаст ошибку компиляции.

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

извини, но примеры полный бред, и вообще не в кассу. я не это спрашивал.

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

тем, что без знания типа компилятор не знает по какому индексу искать указатель на метод в vtbl, и выдаст ошибку компиляции.

curl В чём разница между посылом сообщения и вызовом метода? (комментарий); man VMT; man RTTI

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

и как (в твоем мире) это запрещает считатьь это обработкой сообщений ты нам объяснишь наконец?

первая часть поста вообще шикарна. ты пытался ответить на первую половину моего поста? попробуй еще раз. цитируй те части, где есть вопросительный знак, а после них пиши утверждения, отвечающие на них. у тебя же получилось: «что за хрень ты спорол?» - «именно».

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

ничего. индексы у методов совпадают. попробуй убрать из B foo и bar, вот тогда будет ответ на мой вопрос.

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

Ого. Ты, конечно, совсем чуточку читер, зато теперь понятно, что то ли читать, то ли писать оппонент не умеет.

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

и как (в твоем мире) это запрещает считатьь это обработкой сообщений ты нам объяснишь наконец?

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

первая часть поста вообще шикарна. ты пытался ответить на первую половину моего поста?

я просто согласился с твоей репликой. что не так?

отвечаю на вопрос:

зачем сравниваешь (или не сравниваешь, кто тебя разберет) методы (выход) и сообщения (вход)?

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

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

что то ли читать, то ли писать оппонент не умеет.

читать не умеешь ты. я ни разу не утверждал, что в крестах нельзя вызвать методы одного класса через vtbl другого класса, даже если классы вообще ни разу не связаны. можно например в B переименовать foo в goo, дернуть его, и вызовется foo из A. и хрен с ним. но это _вообще_ никакого отношения не имеет к моему исходному вопросу, от которого fmdw уворачивается как может, хотя ответ очевиден, что кресты так тупо не могут, и это и есть пример отличия между message passing и virtual methods.

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 2)
Ответ на: комментарий от waker

1) fmdw, как ни странно, ответил на тот твой вопрос. именно на твой исходный вопрос. то, что тебе это не нравится и ты безосновательно называешь это «но это _вообще_ никакого отношения не имеет к моему исходному вопросу» ничего не меняет.

2) ты не ответил на мой вопрос. «механизм посылки и обработки сообщений достаточно сильно отличается от крестовых виртуальных методов, чтобы увидеть разницу. если ты ее не видишь - это твои проблемы.» — не ответ, т. к. ты уже постов 5 не можешь показать, где ее узрел ты.

3) ответ на оригинальный вопрос (вопрос ТС) нашли еще теоретики, разговаривавшие только кванторами, и ответ с твоим не совпадает. видимо потому что...

4) ... на крестах мир не сошелся, но, как совершенно правильно заметил fmdw, твои хаотичные знания, полученные явно после первого твоего комментария в этом треде, должен систематизировать второй семестр. а кругозор расширять — это уже потом.

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

именно на твой исходный вопрос.

в моем исходном вопросе говорилось, что у нас есть указатель с типом void *. когда он отмазался, я предложил ему пустой baseclass. такой ответ — да, это натуральный чит, я с тем же успехом могу в крестах достать указатель из vtbl, напрямую из памяти, кастануть его к нужной сигнатуре, и вызвать. но так на вопросы отвечают только шланги.

не ответ, т. к. ты уже постов 5 не можешь показать, где ее узрел ты.

я несколько раз написал, где. не можешь читать - давай дасвидания.

и ответ с твоим не совпадает

давай ссылку на ответ теоретиков. будет интересно просветиться.

на крестах мир не сошелся, но, как совершенно правильно заметил fmdw, твои хаотичные знания, полученные явно после первого твоего комментария в этом треде, должен систематизировать второй семестр. а кругозор расширять — это уже потом.

на этом и разойдемся.

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

Я тут осознал, что в этом коде посылается сообщение, а не вызывается метод :)

$class = "Payments::Paypal";
my $message = "pay";
if($class->can($message)) {
  $class->$message(amount => 50.50, currency => 'RUR');
}
pef-secure
()
Ответ на: комментарий от t184256

твои хаотичные знания, полученные явно после первого твоего комментария в этом треде, должен систематизировать второй семестр

Чувак, на ц++ и тамошнюю кухню мне конечно положить, но ты прежде чем писать такие вещи, хоть поинтересовался бы, кто такой твой оппонент.

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

Мой оппонент? Да какой-то... о господи, боже, боже!.. Это тот самый, который написал для Linux аудиоплеер! А я еще посмел уличать его в том, что он не привел аргумента весомее «они разные»? Посыпаю голову пеплом, его огромный авторитет конечно же с лихвой перевешивает его умение вести дискуссии!

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

кто такой твой оппонент

Аргументация уровня детсада.

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

кресты так тупо не могут

То, что кресты на стадии компиляции превращают имена в индексы — частная особенность крестов. Она не имеет к вопросу ОПа ни малейшего отношения. Там с примерно тем же успехом могли быть словари, хэштаблицы, whatever. То, что ты эту особенность выдаёшь за некую принципиальную разницу между методами и сообщениями — признак дегенерации. Как и любая попытка искать разницу между этими подходами на стороне отправителя. Потому что, в третий раз повторяю, *разница между сообщениями и методами состоит в том, как их обрабатывает получатель.*

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

Это тот самый, который написал для Linux аудиоплеер!

Может плеер и не ядро, но выпады про «хаотичные знания» и «второй семестр» можно придержать, зная, что человек знаком с программированием по крайней мере на сях/плюсах совсем не понаслышке, не считаешь?

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

In computer science, dynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time.

Ты ведь без труда найдёшь принципиальное несоответствие виртуальных методов крестов этому определению?

В крестах нет никакого «process of selecting» при вызове метода. Мы обращаемся по фиксированному смещению в объекте для обращения к vmt, а там, в свою очередь, по фиксированному смещению получаем адрес функции, которую и вызываем. Вся магия заключается в том, что компилятор уже проставил адреса нужных функций и обеспечил установку для каждого объекта нужного адреса vmt. В динамике ничего не ищется(сравни с objective-c).

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

Все мирно беседовали про вопрос ТС, писали милые глупости, и тут он пишет (даже не удосужившись предупредить, что его уютный мирок ограничен крестами) вот это:

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

По ходу обсуждения его замечания становятся несколько лучше, но медленно, что вполне допускает, что знания по теме, в которую зачем-то зашел, он черпает, гугля на ходу. К концу второго дня он так и не разобрался, хотя все поддались на провокацию, снизошли до убогих крестов, решили ему задачку и 10 раз спросили, какие такие отличия он там увидел.

Я не утверждаю, что он не знаком с практически полезными аспектами программирования на плюсах, упаси боже. Но в философскую тему не о плюсах он мог бы и не лезть, а помня побольше из второго семестра — не выглядеть глупо, не считаешь?

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

не удосужившись предупредить, что его уютный мирок ограничен крестами

я вообще почти не пишу на крестах, и ненавижу кресты, и отвечал оппоненту который написал вот это

reinterpret_cast<T>(your_pointer)->someMethodOfT();

раз он хотел говорить про кресты — будем говорить про кресты. в отличие от тебя, я не начал приплетать другие языки, о которых речи и не шло.

(если что, 3 основных проекта, над которыми я тружусь, в основном на C + ObjC, и еще 2 на javascript).

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

Отвечу за него — да, он откажется признать разыменование по известному смещению поиском, и, также, по неизвестным мне соображениям, «process of selecting»'ом.. Что поделать — не знаю. Может ты придумаешь.

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

Или это верно для всех языков, а не только для крестов и какого-нибудь D?

это верно для многих языков, скажем так.

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

Т.е. процесс поиска значения в таблице не является

Там нет никакого поиска. Есть только обращение по заранее известному смещению.

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

он откажется признать разыменование по известному смещению поиском

А где тут поиск? Как раз вся вишка крестовой пародии на ООП в том, что поиска нет и мы просто вызываем функцию по указателю.

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

Мне вообще непонятно, зачем ты придрался к фразе «process of selecting». В приведённом определении нет ни слова о том, что должен представлять из себя этот процесс выбора.

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

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

Я придрался в контексте темы. На мой взгляд, в ООП метод - это обработчик сообщения. vmt - можно с натяжкой считать таблицей соответствия сообщение -> метод, но с учетом того, что она захардкожена. В общем же случае в крестах нет сообщений, есть только методы. И термин «виртуальный метод»/«виртуальная функция член» - чисто крестовая терминология, не имеющая прямого отношения к ООП, лишь к его частной реализации.

Вот в objective-c, для сравнения, мы посылаем сообщение и рантайм ищет для него метод по определенному алгоритму.

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

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

Нет, в рантайме.

class Base;
class Child1 : Base;
class Child2 : Base;

Base* p = new Child1();
p->some_virtual_method();

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

Нет, в рантайме.

В рантайме там будет просто вызов по указателю. vmt создается статически для каждого класса и статически же описывается ее установка в коде конструирования объекта.

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

p->some_virtual_method();

это резолвится в p->vtbl[METHOD_INDEX](p);

METHOD_INDEX = const

адреса в vtbl тоже const. и сам указатель на vtbl const, просто копируется в инстанс при создании.

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

В рантайме там будет просто вызов по указателю. vmt создается статически для каждого класса и статически же описывается ее установка в коде конструирования объекта.

Но именно в рантайме исходя из vmt и будет сформирован нужный указатель.

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

это резолвится в p->vtbl[METHOD_INDEX](p);

Угу, вот потому вызов виртуального метода и считается дороже.

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

похоже, у нас мнение отличается на уровне терминологии, а не на уровне сути вещей. не о чем тут спорить.

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

Сформирован он будет в статике, в рантайме мы просто прочтем это значение.

В компайл-тайм будет сформирована vmt. А в рантайме мы будем считать адрес метода.

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

Не считать, а считывать :)

А что по вашему происходит при выполнении операции pointer[index] до считывания? :)

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