Re[3]: v-table vs if call
От: qaz77  
Дата: 07.12.22 07:56
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Не понял, каждая ячейка отдельный класс что ли?

Нет, конечно.

TB>Или наследование абстрактных классов требует дополнительный указатель в каждом экземпляре?

Да, как частный случай.
В общем случае не только абстрактных, а имеющих хотя бы одну виртуальную функцию.
Re[4]: v-table vs if call
От: T4r4sB Россия  
Дата: 07.12.22 08:00
Оценка: :)
Здравствуйте, qaz77, Вы писали:

Q>Да, как частный случай.

Q>В общем случае не только абстрактных, а имеющих хотя бы одну виртуальную функцию.

Какая-то говняная реализация ООП, это что за говноязык? А, это же С++, в котором не платят за то, чем не пользуются.

Концепция Раста с его жирными указателями, когда в самом классе никаких указателей на таблицы нет, уже не выглядит такой странной, да?
Re[3]: v-table vs if call
От: qaz77  
Дата: 07.12.22 08:09
Оценка:
Здравствуйте, Patalog, Вы писали:

P>Не очень понял как такое получилось В объекте же афаир только vptr, а сама таблица относится в классу, а не к инстансу?

Таблица относится к каждому классу с виртуальными функциями.

В примере Impl содержит vptr для классов Inter1 и Inter2:
#include <iostream>

class Inter1
{
public:
  virtual void foo1() = 0;
};

class Inter2
{
public:
  virtual void foo2() = 0;
};

class Impl final: public Inter1, public Inter2
{
public:
  virtual void foo1() override {}
  virtual void foo2() override {}

private:
  double m_data = 3.14 // sizeof(m_data) == 8
};

int main()
{
  Impl instance;
  std::cout << sizeof(instance) << std::endl;
  return 0;
}


Вывод для x86: 16 (8 + 2 * 4)
Вывод для x64: 24 (8 + 2 * 8)

Я упоминал о приеме, который ценой нарушения принципа "is a" уменьшает размер объекта:
#include <iostream>

class Inter1
{
public:
  virtual void foo1() = 0;
};

class Inter2: public Inter1 // << Inter2 is not a Inter1 !!!
{
public:
  virtual void foo2() = 0;
};

class Impl final: public Inter2 // << Inter2 only!
{
public:
  virtual void foo1() override {}
  virtual void foo2() override {}

private:
  double m_data = 3.14 // sizeof(m_data) == 8
};

int main()
{
  Impl instance;
  std::cout << sizeof(instance) << std::endl;
  return 0;
}


И тут чудесным образом:
вывод для x86: 12 (8 + 1 * 4)
вывод для x64: 16 (8 + 1 * 8)
Re[5]: v-table vs if call
От: qaz77  
Дата: 07.12.22 08:21
Оценка:
Здравствуйте, T4r4sB, Вы писали:
TB>Какая-то говняная реализация ООП, это что за говноязык? А, это же С++, в котором не платят за то, чем не пользуются.

Это еще цветочки.
Настоящая веселуха начинается когда объект содержит в себе несколько подобъектов одного класса.
Или с виртуальным наследованием, ромбы всякие.

С другой стороны, не нравится — не используешь.
Вот я практически не пользуюсь множественным наследованием от не чисто абстрактных классов, а также виртуальным наследованием.
Ромб только в один раз делал, но там задача была 1 в 1 как iostream — in/out сериализация.
Re[6]: v-table vs if call
От: T4r4sB Россия  
Дата: 07.12.22 08:32
Оценка:
Здравствуйте, qaz77, Вы писали:

Q>С другой стороны, не нравится — не используешь.


А если очень надо — то пилишь велосипед?
Re[7]: v-table vs if call
От: qaz77  
Дата: 07.12.22 08:37
Оценка:
Здравствуйте, T4r4sB, Вы писали:
TB>А если очень надо — то пилишь велосипед?

Какие тут велосипеды?
Все эти vptr реализация самого C++, от нее никуда не навелосипедишь.

Или речь про какие-нибудь мультиметоды?
Этого да, иногда не хватает.
Тогда только велосипед
Re[8]: v-table vs if call
От: T4r4sB Россия  
Дата: 07.12.22 08:41
Оценка:
Здравствуйте, qaz77, Вы писали:

Q>Какие тут велосипеды?


Сэмулировать жирные указатели, а в классе никаких указателей на таблицы не хранить. Как в Расте.
Re[9]: v-table vs if call
От: qaz77  
Дата: 07.12.22 08:44
Оценка:
Здравствуйте, T4r4sB, Вы писали:
TB>Сэмулировать жирные указатели, а в классе никаких указателей на таблицы не хранить. Как в Расте.

Наверное можно и так.
Класс сделать без виртуальных функций, а полиморфизм руками наколхозить.
Re[4]: v-table vs if call
От: Patalog Россия  
Дата: 07.12.22 09:15
Оценка: 1 (1)
Здравствуйте, qaz77, Вы писали:

хъ

P>>Не очень понял как такое получилось В объекте же афаир только vptr, а сама таблица относится в классу, а не к инстансу?

Q>Таблица относится к каждому классу с виртуальными функциями.

Q>В примере Impl содержит vptr для классов Inter1 и Inter2:


С vptr все понятно, в исходном сообщении было про vtbl, об чем я и удивился.
Почетный кавалер ордена Совка.
Re[9]: v-table vs if call
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.12.22 09:18
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Сэмулировать жирные указатели, а в классе никаких указателей на таблицы не хранить. Как в Расте.


А что это и как работает?
Маньяк Робокряк колесит по городу
Re[5]: v-table vs if call
От: qaz77  
Дата: 07.12.22 09:19
Оценка:
Здравствуйте, Patalog, Вы писали:

P>С vptr все понятно, в исходном сообщении было про vtbl, об чем я и удивился.


Да, я опустил слово "указатель". Т.е. подразумевалось "указатель на vtbl".
Думал, что из контекста понятно...
Re[10]: v-table vs if call
От: T4r4sB Россия  
Дата: 07.12.22 09:40
Оценка:
Здравствуйте, Marty, Вы писали:

M>А что это и как работает?


Типа если функция принимает указатель на интерфейс, то на самом деле она принимает пару указателей: указатель на объект, и указатель на vtbl, в которой этот объект реализует этот интерфейс.
Как раз чтоб в объекте не хванить все эти указатели на vtbl.
Re[11]: v-table vs if call
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.12.22 10:28
Оценка:
Здравствуйте, T4r4sB, Вы писали:

M>>А что это и как работает?


TB>Типа если функция принимает указатель на интерфейс, то на самом деле она принимает пару указателей: указатель на объект, и указатель на vtbl, в которой этот объект реализует этот интерфейс.

TB>Как раз чтоб в объекте не хванить все эти указатели на vtbl.

Ну, таки где-то эти указатели всё равно хранить надо. И что мешает присунуть не тот указатель на vtbl?
Маньяк Робокряк колесит по городу
Re[12]: v-table vs if call
От: T4r4sB Россия  
Дата: 07.12.22 10:37
Оценка:
Здравствуйте, Marty, Вы писали:

M>Ну, таки где-то эти указатели всё равно хранить надо.


Да, один лишний указатель приходится гонять по стеку. Это лучше, чем в каждом экземпляре хранить 100500 указателей.
Ещё если ты в структуре хранишь Box<dyn MyInderface> (unique_ptr<MyInterface>), то он жрёт вдвое больше.

M>И что мешает присунуть не тот указатель на vtbl?


Если это работает на уровне языка — то у тебя при вот таком:
fn foo(arg: &dyn MyInterface) { // якобы принимает указатель на интерфейс/абстрактный класс с названием MyInterface
...
}
...

let object: MyClass;
foo(&object)

по факту автоматически передастся такая пара:
foo((&object, &vtbl_MyClass_for_MyInterface))

Короче как-то так: https://www.reddit.com/r/rust/comments/8ckfdb/were_fat_pointers_a_good_idea/


Если попытаешься сэмулировать подобное в С++, то я хз, наверное можно как-то извернуться на имплисит конструкторах и шаблонах, чтоб работало более-менее удобно.
Re[13]: v-table vs if call
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.12.22 10:39
Оценка:
Здравствуйте, T4r4sB, Вы писали:

M>>Ну, таки где-то эти указатели всё равно хранить надо.


TB>Да, один лишний указатель приходится гонять по стеку. Это лучше, чем в каждом экземпляре хранить 100500 указателей.

TB>Ещё если ты в структуре хранишь Box<dyn MyInderface> (unique_ptr<MyInterface>), то он жрёт вдвое больше.

А если объект реализует много интерфейсов? Где эти указатели хранятся

Так-то в C++, если объект реализует один интерфейс, то и указатель на vtbl будет один, и никаких проблем
Маньяк Робокряк колесит по городу
Re[14]: v-table vs if call
От: T4r4sB Россия  
Дата: 07.12.22 10:47
Оценка:
Здравствуйте, Marty, Вы писали:

M>А если объект реализует много интерфейсов? Где эти указатели хранятся


Посмотри ещё раз на мой пример — зачем что-то хранить в объекте?
Re[15]: v-table vs if call
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.12.22 10:51
Оценка:
Здравствуйте, T4r4sB, Вы писали:

M>>А если объект реализует много интерфейсов? Где эти указатели хранятся


TB>Посмотри ещё раз на мой пример — зачем что-то хранить в объекте?


Ну, не в объекте, а вместе с ним. Какая разница?
Маньяк Робокряк колесит по городу
Re[16]: v-table vs if call
От: T4r4sB Россия  
Дата: 07.12.22 10:54
Оценка:
Здравствуйте, Marty, Вы писали:

M>Ну, не в объекте, а вместе с ним. Какая разница?


Разница в том, что объект не жиреет от переизбытка интерфейсов.
Указатель на интерфейс собирается в пару с указателем на объект только тогда, когда интерфейс реально становится нужен.
Re[17]: v-table vs if call
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 07.12.22 11:08
Оценка:
Здравствуйте, T4r4sB, Вы писали:

M>>Ну, не в объекте, а вместе с ним. Какая разница?


TB>Разница в том, что объект не жиреет от переизбытка интерфейсов.

TB>Указатель на интерфейс собирается в пару с указателем на объект только тогда, когда интерфейс реально становится нужен.

А, ну попонятнее стало. Типа есть какая-то отдельная таблица указателей на VTBL тех интерфейсов, которые поддерживает объект? Да, по идее, должно места сэкономить. А как dynamic_cast работает? Можно из одного интерфейса получить другой или ошибку, если не поддерживается? Ну и лишняя косвенность вроде как получается, хотя и не при каждом вызове виртуального метода, а только при передаче объекта.

В принципе, в плюсах подобное тоже можно сделать, будет не слишком удобно, но оно точно вот так постоянно надо? Не так часто объекты реализуют множество различных интерфейсов, и не так часто эти объекты настолько малы и их так много, чтобы это играло какую-то заметную роль
Маньяк Робокряк колесит по городу
Re[16]: v-table vs if call
От: night beast СССР  
Дата: 07.12.22 11:11
Оценка:
Здравствуйте, Marty, Вы писали:

M>>>А если объект реализует много интерфейсов? Где эти указатели хранятся

TB>>Посмотри ещё раз на мой пример — зачем что-то хранить в объекте?
M>Ну, не в объекте, а вместе с ним. Какая разница?

struct IPoint {
   virtual ~IPoint() {}
};

struct Point2d : IPoint {
   int16_t x;
   int16_t y;
};


Point2d line[100];
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.