Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Передача указателя на класс в DLL  (Прочитано 23201 раз)
0 Пользователей и 1 Гость смотрят эту тему.
jur
Помогающий

lt
Offline Offline

« : 04-03-2008 09:05 » 

Привет!

Что-то никак не могу понять, как правильно написать класс, чтобы его можно было передать в свою DLL'ку. Вопрос вот в чем. Имеется такой класс:

class CMyClass
{
public:
  CMyClass();
  ~CMyClass();

public:
  int GetMyVar();

private:
  int _my_var;
};

В основной программе создается экземпляр класса:

CMyClass* pMyClass = NULL;
...
pMyClass = new CMyClass;

и вызывается функция в DLL'ке с параметром - адресом созданного класса:

my_result = fnClassProbe_dll(pMyClass);

В DLL'ке я пишу следующее:

CLASSPROBE_DLL_API int fnClassProbe_dll(CMyClass* pMyClass)
{
  return pMyClass->GetMyVar();
}

При компиляции DLL'ки выдается ошибка линкера:

1>ClassProbe_dll.obj : error LNK2001: unresolved external symbol "public: int __thiscall CMyClass::GetMyVar(void)" (?GetMyVar@CMyClass@@QAEHXZ)
1>C:\1my\3SCUSBRev2\PC_other\ClassProbe_dll\Debug\ClassProbe_dll.dll : fatal error LNK1120: 1 unresolved externals

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

Если в определении класса написать:

public:
  virtual int GetMyVar();

то ошибки линкера не возникает и все работает правильно. Хотелось бы понять, почему это происходит? Или просто не думая лепить для всех вызываемых методов virtual? Объясните, пожалуйста!
Записан

MPEG-4 - в массы!
sss
Специалист

ru
Offline Offline

« Ответ #1 : 04-03-2008 09:38 » 

Если ты не напишешь virtual, компилятор будет искать реализацию метода CMyClass::GetMyVar() (вычислять адрес прыжка) в коде проекта dll. Иначе, отложит решение вычисления адреса до времени выполнения (чтение из VTM). Можно не применять virtual, тогда надо добавить cpp файл в проект, что приведет к тому, что у тебя будет код класса как в dll, так и в exe.

P.S.: Возможно, еще можно применить extern...
« Последнее редактирование: 04-03-2008 09:40 от sss » Записан

while (8==8)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #2 : 04-03-2008 09:42 » 

а не поможет ли:

файл
имя_длл.def , содержимое
Код:
LIBRARY      "dll"

EXPORTS
         CMyClass


?
Записан

sss
Специалист

ru
Offline Offline

« Ответ #3 : 04-03-2008 09:59 » 

Алексей1153++, ты уж тогда полностью отвечай что с ним делать. Или он все таки нужен для указания линкеру, какие функции описать в секции экспортов dll? И тем более CMyClass описан в exe проекте.
Записан

while (8==8)
jur
Помогающий

lt
Offline Offline

« Ответ #4 : 04-03-2008 10:40 » 

Если ты не напишешь virtual, компилятор будет искать реализацию метода CMyClass::GetMyVar() (вычислять адрес прыжка) в коде проекта dll.

Похоже, что именно это он и пытается сделать. Но мне непонятно, почему он ищет реализацию метода в коде DLL'ки, если ему ясно сказано, что доступ к классу происходит через указатель? Т.е. я предполагал, что в DLL'ке будет вычисляться адрес метода относительно переданного адреса класса и этот метод вызовется. Причем, именно так все и происходит, если в декларацию метода добавить virtual.

У меня складывается впечатление, что без virtual компилятор пытается... Даже и не знаю, что он пытается... Породить собственный экземпляр класса в DLL'ке он не может, т.к. нет файла *.cpp, а линковаться напрямую к методу класса, IMHO, нет смысла, т.к. в DLL'ку передан указатель на класс, от которого по идее и надо плясать. Не понимаю...

Иначе, отложит решение вычисления адреса до времени выполнения (чтение из VTM).

Вот именно это я сначала и предполагал. Т.е. что адрес метода будет вычисляться относительно переданного указателя. Какие тут могут быть "linker error"?... Причем, с применением virtual именно это вычисление и происходит. Непонятно, почему правильное вычисление адреса метода происходит именно с virtual? Ведь и без virtual этот адрес должен бы вычисляться точно так же.

Может быть тут зарыта какая-то особенность ООП?

а не поможет ли:

файл
имя_длл.def , содержимое
Код:
LIBRARY      "dll"

EXPORTS
         CMyClass
?

Не думаю. Я ведь не экспортирую CMyClass из DLL'ки, а передаю адрес этого класса в качестве параметра функции. Мне нужно, чтобы существовал единственный экземпляр этого класса, и существовал в EXE'шнике.
Записан

MPEG-4 - в массы!
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #5 : 04-03-2008 11:00 » 

Прежде всего нужно понимать, как работает вызов класса.
делая вызов class.method()
ты на сам деле делаешь вызов class_method_func(class*);
т.е. не явно передаётся указатель на сам класс(в питоне это видно из самого синтаксиса языка)

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

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

Странно всё это....
jur
Помогающий

lt
Offline Offline

« Ответ #6 : 04-03-2008 12:22 » 

Прежде всего нужно понимать, как работает вызов класса.
делая вызов class.method()
ты на сам деле делаешь вызов class_method_func(class*);
т.е. не явно передаётся указатель на сам класс(в питоне это видно из самого синтаксиса языка)

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

Так вот оно что! Тогда я понимаю мою ошибку: я почему-то думал, что методы класса (или его данные) всегда отыскиваются посредством указателя на класс this. А получается, что все гораздо запущеннее...

Посмотрел в ассемблерный листинг другого своего проекта (компилятор - gcc-2.95.3-h8300h) - там именно так, как ты говоришь. Да... C++ - "Штука коническая!" (С) :-)

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

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

Еще чуток поясни, пожалуйста. Как пользоваться указателем на интерфейс класса? Я до сих пор применял две технологии:

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

2. В EXE'шнике порождал экземпляр класса и вовне передавал адрес этого экземпляра. Вот тут мне и потребовалось использовать ключевое слово virtual.

А как пользоваться интерфейсами класса?
Записан

MPEG-4 - в массы!
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #7 : 05-03-2008 06:00 » 

Еще чуток поясни, пожалуйста. Как пользоваться указателем на интерфейс класса? Я до сих пор применял две технологии:

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

2. В EXE'шнике порождал экземпляр класса и вовне передавал адрес этого экземпляра. Вот тут мне и потребовалось использовать ключевое слово virtual.

А как пользоваться интерфейсами класса?

Я работаю с интерфейсами примерно так:
1. описываю интерфейс
Код:
class IClass
{
public:
virtual do() = 0;
virtual do2(int) = 0;
virtual ~IClass() = 0;
};
требования к интерфейсу у меня такие:
1.1. Как минимум один метод чисто виртуальный, это не даст создать экземпляр класса интерфейса
1.2. Виртуальный деструктор, рекомендуется делать всегда, если предполагается, что от класса будут наследоваться иначе могут быть проблемы с разрушением объектов вот в таком коде(не обязательно для статического полиморфизма)
Код:
class IClass
{
public:
virtual do() = 0;
virtual do2(int) = 0;
virtual ~IClass();
};

class A: public IClass
{
virtual do();
virtual do2(int);
virtual ~IClass();
}

A * a = new A();
IClass * i = a;
delete i; // если деструктор не виртуальный, то не будет вызван деструктор A

2. создаю класс унаследованный от интерфейса, кстати рекомедую слово virtual в наследнике тоже указывать, этого не требует стандарт, но так понятней будет и тебе и тем, кто отнаследуется от твоего наследника.
3. пользуюсь внутри модуля классом как обычно, в большенстве случаев компилятор убирает обращение к таблице виртуальных функций, если это возможно, оптимизация такая Улыбаюсь
4. при прередаче во вне класса передаю указатель на интерфейс класса
foo(IClass *);

A a; // наследник IClass
foo(&a);

вот как-то так.

единственное могут быть проблемы, если ты используешь различные компиляторы для различных библиотек(таблички виртуальных функций могут поразному выглядеть), но это часто надуманная проблема Улыбаюсь
Есть и не надуманные проблемы с передачей объектов через границу модуля, но опять же на них еще суметь напороться, например, был у меня случай, когда я передавал std::string в скомпилированныю в VC++ библиотеку, из exe собранного в gcc, и у меня были проблемы с разрушением этой строки после, того, как она была заполнена в библиотеке

так-что нужно четко представлять, что ты делаешь
Записан

Странно всё это....
jur
Помогающий

lt
Offline Offline

« Ответ #8 : 08-03-2008 20:53 » 

Я работаю с интерфейсами примерно так:

Большое спасибо за разъяснение! Буду осмысливать.
Записан

MPEG-4 - в массы!
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #9 : 10-03-2008 20:05 » 

ЭЭЭхх всем привет, давно я тут не был... Ну и как обычно мелкие уточнения...
to jur
Интерфейс это абстрактный класс (все функции которого чисто виртуальные), соответственно пункт 1.1 лишний.

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

В том что компилятор ЧАСТО убирает (оптимизирует) вызовы выртуальных функций, это мягко говоря не верно, строго говоря это верно только при условии что функция мембер вызывается из дргугой функции мембера этого же класса или ели вызов происходит из того же места где был создан сам объект, в любых других случаях оптимизация невозможна потому, что компилятор не знает, да и знать не может у какого именно объекта (точный его тип) вызывается функция.

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

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

С уважением Lapulya
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 10-03-2008 20:45 » 

Цитата: lapulya
Для преодоления проблемы передачи объекта между модулями надо следовать простому правилу, кто согдает объект, тот его и уничтожает, а еще строже и применительно к данному вопросу, объект должен создаваться и уничтодаться в одногм и томже модуле.
Довольно сомнительное правило для конвейерных обработок с ветвлениями и прочей сложной маршрутизацией. Нарушает инкапсуляцию, заставляя открывать фабрику/утилизатор для всего конвейера. И не всегда такая фабрика - хороший кандидат в одиночки.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
jur
Помогающий

lt
Offline Offline

« Ответ #11 : 11-03-2008 01:00 » 

to jur
Интерфейс это абстрактный класс (все функции которого чисто виртуальные), соответственно пункт 1.1 лишний.
...
ты пишешь
"единственное могут быть проблемы, если ты используешь различные компиляторы для различных библиотек(таблички виртуальных функций могут поразному выглядеть), но это часто надуманная проблема"

Вообще-то это не я писал... Но все равно спасибо за разъяснение! :-)

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

Мне вообще нужна крайне простая вещь: возможность использования классов, созданных в основной программе, в DLL'ках, которые являются вспомогательными модулями основной программы. (Речь идет о программе работы прибора. Довольно простого. Ультразвукового сканера, вспомогательные модули которого выполняют несложные, атомарные операции: запуск сканирования, выполнение измерений, сохранение результатов в файлах.)
Записан

MPEG-4 - в массы!
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #12 : 11-03-2008 17:36 » 

to dimka,
ну открывать фабрику и уж тем более делать ее одиночкой я не предлагал. При достаточно больших программах хождение объекта по системе может быть довольно велико и если не будет подобной фабрики, то велика вероятность утечки памяти. Кроме того это гарантия того, что при межмодульном взаимодействии объект будет уничтожен в том же модуле, что и был создан (понятно, что отсутствие подобной фабрики сильно усложняет задачу)

Кстате не вижу проблемы использовате фабрики при использовании конвейерных обработок с ветвлениями и прочей сложной маршрутизацией. Если есть сомнения пишите...
Записан

С уважением Lapulya
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 11-03-2008 19:42 » 

Цитата: lapulya
Если есть сомнения пишите...
Я уже написал выше - меня беспокоит ослабление инкапсуляции. И написал, почему меня это беспокоит.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #14 : 12-03-2008 04:58 » 

to jur
Интерфейс это абстрактный класс (все функции которого чисто виртуальные), соответственно пункт 1.1 лишний.

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

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

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

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

В том что компилятор ЧАСТО убирает (оптимизирует) вызовы выртуальных функций, это мягко говоря не верно, строго говоря это верно только при условии что функция мембер вызывается из дргугой функции мембера этого же класса или ели вызов происходит из того же места где был создан сам объект, в любых других случаях оптимизация невозможна потому, что компилятор не знает, да и знать не может у какого именно объекта (точный его тип) вызывается функция.

Верно-верно сам проверял(смотрел ассемблерный код).
делал тест:
1. обращение к методам из нутри самого объекта
2. обращение к методам объекта на стеке
3. обращение к методам объекта на куче
4. обращение к методам объекта через указатель на базовый класс

механизм полиморфизма использовался только в случае №4.
Записан

Странно всё это....
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #15 : 12-03-2008 05:09 » 

to dimka,
ну открывать фабрику и уж тем более делать ее одиночкой я не предлагал. При достаточно больших программах хождение объекта по системе может быть довольно велико и если не будет подобной фабрики, то велика вероятность утечки памяти. Кроме того это гарантия того, что при межмодульном взаимодействии объект будет уничтожен в том же модуле, что и был создан (понятно, что отсутствие подобной фабрики сильно усложняет задачу)

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

Ни что не мешает реализовать для интерфейса свои new и delete

Наличие фабрики не гарантирует утечек, вообще не гарантирует, вот хоть бошку об стену расшиби.

Фабрики, как и одиночки нахожу довольно вредной концепцией, стимулирущей появление гибридного кода и при не ОЧЕНЬ окуратном кодировании сложно уловимых ошибок в много поточных приложениях, но это моё мнение.

Записан

Странно всё это....
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 12-03-2008 12:45 » 

Цитата: LogRus
Не обязательно. Например могут понадобится некоторые методы реализованные уже в интерфейсе, достаточно общие, что бы не пораждать лишнего наследования.
Тогда это просто абстрактный класс, а не интерфейс. Улыбаюсь

Цитата: LogRus
Наличие фабрики не гарантирует утечек, вообще не гарантирует, вот хоть бошку об стену расшиби.

Фабрики, как и одиночки нахожу довольно вредной концепцией, стимулирущей появление гибридного кода и при не ОЧЕНЬ окуратном кодировании сложно уловимых ошибок в много поточных приложениях, но это моё мнение.
Мне показалось, что речь шла, скорее о стилистических соглашениях о кодировании между программистами, нежели о безусловном предотвращении ошибок сущностью самого решения.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #17 : 12-03-2008 14:32 » 

Уговрили Улыбаюсь тяжелое утро.

Хотя о фабриках можно и поспорить
Записан

Странно всё это....
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #18 : 13-03-2008 06:03 » 

to LogRus
до кучи
Цитата
Цитата: lapulya от 10-03-2008 17:05
Цитата
Вируальность деструктора необходима, а не рекомендована в случае, когда от класса будет наследование (в случае интерфейса, ну или при наличии в классе хотябы одной чисто виртуальной функции это неизбежно).

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

Если не делать приведения указателя к базовому классу...)))))), то мне вообще не понятно зачем программировать на С++... зачем нужен полиморфизм, виртуальные функции и т.д. и т.п.... и в конечном счете ООП?

Цитата
Цитата: lapulya от 10-03-2008 17:05
Цитата
единственное могут быть проблемы, если ты используешь различные компиляторы для различных библиотек(таблички виртуальных функций могут поразному выглядеть), но это часто надуманная проблема
Если честно точно не скажу (уж года 4 как ничего не писал ))) ), но вроде такой проблемы быть не может, это гарантирирует стандарт (естественно что некоторые компиляторы могут ему не следовать).


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

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

Цитата
Цитата: LogRus
Цитата
Наличие фабрики не гарантирует утечек, вообще не гарантирует, вот хоть бошку об стену расшиби.

Фабрики, как и одиночки нахожу довольно вредной концепцией, стимулирущей появление гибридного кода и при не ОЧЕНЬ окуратном кодировании сложно уловимых ошибок в много поточных приложениях, но это моё мнение.
Мне показалось, что речь шла, скорее о стилистических соглашениях о кодировании между программистами, нежели о безусловном предотвращении ошибок сущностью самого решения.

есессно о соглашении, никто программеру (кроме другого программера или лида) голову не оторвет если он в обход фабрики сам бъект создаст, или даже создав объект через фабрику не забудет его грохнуть, но можно это дело ужесточить ))) например для последнего (я про удаление)... например фабрика при создании объекта увеличивает счетчик, а при удалении уменьшает на 1, а в деструкторе проверяет счетчик на 0 и если он ему не равен мы берем дубину... с созданием можно теже попариться ... например с приватным конструктором...

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

Без обид, ничего личного, только С++
« Последнее редактирование: 13-03-2008 06:09 от lapulya » Записан

С уважением Lapulya
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #19 : 13-03-2008 07:22 » 

Если не делать приведения указателя к базовому классу...)))))), то мне вообще не понятно зачем программировать на С++... зачем нужен полиморфизм, виртуальные функции и т.д. и т.п.... и в конечном счете ООП?

Улыбаюсь есть такое понятие, как статический полиморфиз Улыбаюсь лично для меня он во многих случаях предпочтительней динамического(ну не нужен мне динамический)
Согласен код растёт, бинарники жирные получаются, но
1. нет накладных расходов на полиморфизм
2. удобно

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

Без обид, ничего личного, только С++

ясен пень Улыбаюсь
Записан

Странно всё это....
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #20 : 14-03-2008 09:40 » 

А что такое статический полиморфизм? Я чего то упустил или это что-то новое (я просто не в курсе может новый стандарт вышел, я ж говорю, 4 года ничего не писал)?
Записан

С уважением Lapulya
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #21 : 14-03-2008 09:42 » 

lapulya, темка перехала.

Под статическим полиморфизмом я подразумеваю полиморфизм доступный еще на стадии компиляции.

продолжение в новой теме
Записан

Странно всё это....
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines