Russian Qt Forum
Март 29, 2024, 10:54 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3] 4 5   Вниз
  Печать  
Автор Тема: Шаблонный виртуал  (Прочитано 28410 раз)
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #30 : Сентябрь 03, 2017, 16:11 »

вам осталось осознать,
что vtbl в dll
и vtbl в итоговом exe
абсолютно обратно совместимы.
потому и проблем никаких.
Вам осталось осознать, что патчить или подменять таблицы пока некому.
Учить загрузчик таким чудесам - глупо, учить компилятор генерить код для загрузки dll и коррекции vtbl - тоже.
Можно конечно пойти по пути Go и генерировать один бинарный блоб содержащий все-все-все...
А так, можно сделать все...

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

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

свои глупости оставьте себе.
Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4349



Просмотр профиля
« Ответ #31 : Сентябрь 03, 2017, 16:15 »

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

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

свои глупости оставьте себе.

Вам осталось осознать, что я не говорю о технических ограничениях. Повторю, сделать можно все, только почему-то не сделано.
Почему?

Ждем очередной бред.
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #32 : Сентябрь 03, 2017, 16:21 »

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

ваш К. О.

При чём тут таблицы импорта? Ну добавит компилятор в приложении в vtbl новый указатель на метод, только код для этого метода он откуда возьмёт?

какой то странный вопрос...

звучит примерно так:
- у нас есть vtbl, как нам теперь запустить метод наследника через базовый интерфейс?
- выполнить запуск по указателю в vtbl? не, не слышал.
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #33 : Сентябрь 03, 2017, 16:21 »

Вам осталось осознать, что я не говорю о технических ограничениях. Повторю, сделать можно все, только почему-то не сделано.
Почему?

Ждем очередной бред.

см выше.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #34 : Сентябрь 03, 2017, 16:52 »

Ну добавит компилятор в приложении в vtbl новый указатель на метод, только код для этого метода он откуда возьмёт? 
Так он же сам его и создает при "инстанциации" нового типа
Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #35 : Сентябрь 03, 2017, 16:57 »

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

ваш К. О.

При чём тут таблицы импорта? Ну добавит компилятор в приложении в vtbl новый указатель на метод, только код для этого метода он откуда возьмёт?

какой то странный вопрос...

звучит примерно так:
- у нас есть vtbl, как нам теперь запустить метод наследника через базовый интерфейс?
- выполнить запуск по указателю в vtbl? не, не слышал.

Мда... Ну давайте разжуём про интерфейс - реализацию.

1. Библиотека.

ISomeClass.h
Код
C++ (Qt)
class ISomeClass
{
   ...
   template <class T>
   virtual void doSomething(T value) = 0;
}
 

SomeConcreteClass.h
Код
C++ (Qt)
#include <ISomeClass.h>
 
class SomeConcreteClass : public ISomeClass
{
   ...
   template <class T>
   void doSomething(T value) override
   {
        std::cout << "SomeConcreteClass  value = " << value << std::endl;
   }
}
 

SomeLibrary.h
Код
C++ (Qt)
#include <ISomeClass.h>
 
ISomeClass * makeSomeObject();
 

SomeLibrary.cpp
Код
C++ (Qt)
#include <SomeConcreteClass.h>
ISomeClass * makeSomeObject()
{
   return new SomeConcreteClass();
}
 

где-то во внутренностях библиотеки есть вызовы
Код
C++ (Qt)
ISomeClass * some_object = makeSomeObject();
some_object->doSomething(int(10));
some_object->doSomething(double(5.7));
 

Библиотека компилируется, для ISomeClass/SomeConcreteClass формируется vtbl с doSomething(int) и doSomething(double()), которые ссылаются на код, сгенерированный на основе SomeConcreteClass::doSomething() из файла SomeConcreteClass.h. Получается бинарник SomeLibrary.dll, и чтобы его могли подключать, пользователям библиотеки дают заголовки SomeLibrary.h и ISomeClass.h. Файл SomeConcreteClass.h не дают.

2. Приложение.

Приложению доступны заголовки SomeLibrary.h, ISomeClass.h и бинарник SomeLibrary.dll. Разработчик создаёт объект:
Код
C++ (Qt)
ISomeClass * some_object = makeSomeObject();
 
и далее вызывает шаблонный метод с типом, которого нет в библиотеке:
Код
C++ (Qt)
QWidget * widget = new QWidget();
some_object->doSomething(widget);
 

На какой код будет ссылаться указатель в vtbl для doSomething(QWidget)? Если код должен генерироваться на основе SomeConcreteClass::doSomething(), который находится в файле SomeConcreteClass.h, которого у пользователя библиотеки физически нет.
Записан

Пока сам не сделаешь...
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4349



Просмотр профиля
« Ответ #36 : Сентябрь 03, 2017, 17:02 »

см выше.
А что там выше? Улыбающийся
Заявления о отсутствии технических трудностей, так это мы и без вас знали.
АйТи область она такая... с наличием интереса все можно сделать... а с деньгами... так вообще. Улыбающийся
Фича полезная, но не сделана... Комитет уже метаклассы там добавляет, а такую простую штуку сделать не могут...

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

Записан
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4349



Просмотр профиля
« Ответ #37 : Сентябрь 03, 2017, 17:20 »

На какой код будет ссылаться указатель в vtbl для doSomething(QWidget)? Если код должен генерироваться на основе SomeConcreteClass::doSomething(), который находится в файле SomeConcreteClass.h, которого у пользователя библиотеки физически нет.
В данном случае компилятору придется не метод генерировать, а ошибку компиляции. Вызывать можно будет только те методы, инстанции которых были определены.
Записан
Bepec
Гость
« Ответ #38 : Сентябрь 03, 2017, 18:25 »

Тема зашла в тупик.
Им одно, они второе, им первое, они четвертое.

1) необходимость введения данной поддержки на всех платформах.
2) необходимость поддержки "старых" либ.
3) изменение структуры Dll для поддержки новых возможностей. (как следствие программы для работы со старыми dll не будут работать с новыми)
4) введение синтаксиса "разрешённых/запрещённых" виртуальных методов. (Не все хотят чтобы их классы вертели как хотели. )
5) увеличение времени компиляции/запуска/линковки всех программ.
6) как следствие из вышеперечисленного необходимо переписывать ОГРОМНЕЙШИЙ пласт программ, использующих Dll, перекомпиляция почти всех продаваемых продуктов, систем защиты dll и прочего.

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

PS ни одна компания не выделит деньги на внедрение этого нового стандарта за просто так. Нужна очень веская причина для изменения устоев.
PPS ничто не мешает вам самим написать собственный компилятор, с необходимым функционалом. И будет это не "новые dll", а плагины ваши.
« Последнее редактирование: Сентябрь 03, 2017, 18:27 от Bepec » Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #39 : Сентябрь 03, 2017, 18:28 »

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

Вот Улыбающийся. Уже варианты пошли. Вместо однообразных мантр некоторых, что "компилятор сам кода нагенерит и vtbl поправит". Сколько ещё всяких особенностей отыщется, если копнуть поглубже.
Записан

Пока сам не сделаешь...
Old
Джедай : наставник для всех
*******
Online Online

Сообщений: 4349



Просмотр профиля
« Ответ #40 : Сентябрь 03, 2017, 18:38 »

Сколько ещё всяких особенностей отыщется, если копнуть поглубже.
Вот и я про это.
Мы тут даже решить не можем кто все это будет делать? Улыбающийся Находить библиотеки в памяти процесса, выбирать из них vtbl, расширять новыми методами, патчить процесс в памяти на новые таблицы?
Компилятор? Не слишком дофига ему придется узнать о целевой платформе, для генерации всех этих чудес.
Загрузчик? Нахрен ему все эти заморочки, связанные исключительно с плюсовыми процессами и библиотеками.

А так ограничений нет. Улыбающийся
« Последнее редактирование: Сентябрь 03, 2017, 18:42 от Old » Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #41 : Сентябрь 03, 2017, 23:43 »

Мда... Ну давайте разжуём про интерфейс - реализацию.

понял вопрос.
рассмотрим класс:

Код:
class ISomeClass
{
    template <class T>
    virtual void doSomething(T value) = 0;
}

сам по себе шаблон-виртуал ничего не значит,
если нет инстанций.

допустим в нашей библиотечке есть класс:

Код
C++ (Qt)
#include <ISomeClass.h>
class SomeConcreteClass : public ISomeClass
{
 
   template <class T>
   void doSomething(T value) override
   {
        std::cout << "SomeConcreteClass  value = " << value << std::endl;
   }
}
 

его реализация так же ничего не значит до тех пор,
пока нет инстанций.

но вот тут компилятор видит вызовы шаблоно-виртуалов:

Код
C++ (Qt)
ISomeClass * some_object = makeSomeObject();
some_object->doSomething(int(10));
some_object->doSomething(double(5.7));
 

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

и такое инстанцирование аналогично тому,
как если бы мы вручную сделали:

Код:
class ISomeClass
{
    virtual void doSomething(int value) = 0;
    virtual void doSomething(double value) = 0;
}

class SomeConcreteClass : public ISomeClass
{
    void doSomething(int value) override
    {
         std::cout << "SomeConcreteClass  value = " << value << std::endl;
    }
    void doSomething(double value) override
    {
         std::cout << "SomeConcreteClass  value = " << value << std::endl;
    }
}

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

сама библиотека содержит реализации самых обычных
виртуальных методов.

именно такой подход я имел ввиду,
когда выше писал:
"шаблоно-виртуал - не более чем просто сахарок,
который реализует автоматическую копипасту"

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

интересное дальше:

при компиляции итогового приложения,
компилятор видит вызов метода с ещё одним параметром:

Код:
some_object->doSomething(new QWidget());

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

Код:
class ISomeClass
{
    virtual void doSomething(int value) = 0;
    virtual void doSomething(double value) = 0;
    virtual void doSomething(QWidget* value) = 0;
}

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

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

в действительности,
дизайн полиморфизма с++ с его классовой системой
просто технически не способны защитить от подобных ошибок:

http://rextester.com/LVWMK76234

Код:
#include <iostream>

struct base
{
    virtual void doSomething(int value) = 0;
   
    base* sample = nullptr; // <--- regular in real code
};


struct concrete: base
{
    ~concrete()
    {
        sample->doSomething(10); // <--- upps
    }
   
};

struct der: concrete
{
    der()
    {
        this->sample = this; // bomb
    }
   
    virtual void doSomething(int value)
    {
        std::cout <<"doSomething("<<value<<")\n";
    }
};

int main()
{
    der d;  //<--- babah!!!
}


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

(я только у новичков встречал, например)

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

выдавать наружу интерфейс на внутреннего наследника,
содержащего шаблонно-виртуал - ССЗБ.



Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #42 : Сентябрь 03, 2017, 23:49 »

А что там выше? Улыбающийся

если в 5ти словах, то там вот это:
А я думаю не хотят.

если не в 5ти словах - почитайте тему.

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





Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #43 : Сентябрь 04, 2017, 00:00 »

1) необходимость введения данной поддержки на всех платформах.
такой необходимости никогда не существовало.
на практике разные компиляторы в разной степени
поддерживают стандарт.

2) необходимость поддержки "старых" либ.
обратная совместимость? не, не слышал.


3) изменение структуры Dll для поддержки новых возможностей. (как следствие программы для работы со старыми dll не будут работать с новыми)
обратная совместимость? не, не слышал.


4) введение синтаксиса "разрешённых/запрещённых" виртуальных методов. (Не все хотят чтобы их классы вертели как хотели. )
вы это о чем?

override/final/delete вам не достаточно?
хочется чего то ещё?

5) увеличение времени компиляции/запуска/линковки всех программ.
это такой традиционный недостаток с++,
на которой традиционно все кладут
предварительно скомпилированный заголовок? не не слышал

на запуск шаблоны вообще никак не влияют
после компиляции никаких шаблонов уже не существует. не существует, Карл!!!


6) как следствие из вышеперечисленного необходимо переписывать ОГРОМНЕЙШИЙ пласт программ, использующих Dll, перекомпиляция почти всех продаваемых продуктов, систем защиты dll и прочего.
обратная совместимость? не, не слышал.
Записан
Bepec
Гость
« Ответ #44 : Сентябрь 04, 2017, 02:32 »

Вы, конечно, молодец, Написали много текста с комментариями типо "не слышал", но это не отменяет всей работы.
Чтобы добавить такие фичи нужен стандарт. Время + деньги.
Чтобы реализовать этот стандарт, пусть даже на простейшем mingw+msvc нужен труд десятков, если не сотен людей. Время + деньги.
Чтобы поддерживать и старые и новые либы, дабы IDE работали как надо, надо дописать все IDE. Ну штук 20 их точно есть, не учитывая непопулярные. Время + деньги.
Увеличение времени компиляции каждой либы на 0,2с ведёт к... Время + деньги. Маленькое время и маленькие деньги, но зато много либ.
И насчёт переписывания программ - я имел в виду огромнейший пласт программ, которые ИСПОЛЬЗУЮТ, АНАЛИЗИРУЮТ, ПРАВЯТ, ЗАЩИЩАЮТ функционал dll. Т.е.  добавление нового функционала, а не переписывание старого. Да даже добавление нового формата. Время + деньги.

Вот скажите, сколько людей здесь и сейчас, остро нуждаются в этой фиче?
Отвечу - разве что Igors. Ибо данный функционал можно заменить имеющимся. Было бы желание.

PS думаю всё скатилось в "а вот хочу", вместо "а вот нужно".
PPS я вот к примеру всё чаще прихожу к мнению что ООП типа "черный ящик" это тупик для программирования. Что должна быть открытость членов, данных, информации, которая открывает чрезвычайные перспективы. Но даже если я соберу сотни тысяч последователей, реализовывать данный функционал в стандарте не будут. Ибо тут не вводить надо, а ломать всё старый и делать новый стандарт. 

Записан
Страниц: 1 2 [3] 4 5   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.231 секунд. Запросов: 22.