Re[3]: Телепаты-то в отпуске!
От: Centaur Россия  
Дата: 17.09.10 04:59
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>class Exporting
S>{
S>public:
S>  virtual int func() = 0;
S>  virtual float other() = 0;
S>};


Это поломается при использовании между компиляторами с разным размером и/или представлением int и float или разной конвенцией вызовов по умолчанию. На Windows я бы переписал так:

class Exporting
{
public:
  virtual INT __stdcall func() = 0;
  virtual DOUBLE __stdcall other() = 0;
};


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

Ну и если в реализующем классе используются какие-нибудь классы (std::string, контейнеры, etc.), в интерфейсе их показывать нельзя. Можно дать доступ к внутренностям (s.c_str(), s.data(), &*s.begin(), &s[0]), с учётом времени жизни соответствующих ссылок и указателей.

S>class My : public Exporting
S>{
S>public:
S>  int funct() { return m_str.size(); }
S>  float other() { return 4.4; } 
S>private:
S>  std::string m_str;
S>};

S>extern "C"
S>{
S>  Exporting * getClass();
S>}
S>Exporting * getClass()
S>{
S>  return new My();
S>}


Здесь ещё нужен механизм удаления. Либо extern "C" void deleteObject(Exporting *), либо метод в интерфейсе. Идиоматично будет сразу навернуть в интерфейсе интрузивный подсчёт ссылок через AddRef() / Release() и выполнять delete this из Release(), когда счётчик ссылок падает до нуля.

С клиентской стороны можно добавить умный указатель, инкапсулирующий вызовы AddRef/Release (в случае подсчёта ссылок) или Clone/deleteObject (в случае обычного владения).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.