как использовать класс
От: sergey2b ЮАР  
Дата: 03.02.17 13:02
Оценка:
Подскажите пожалуйста как ответить на такой вопрос

имееться определение класса A
который используеться в 16 Gb кода

как надо организовать использование класса A так что бы
изменение его определение (скажем добавили новый метод) не вызывало полной перекомпиляции используещего его кода
Re: как использовать класс
От: watchmaker  
Дата: 03.02.17 13:26
Оценка: +2
Здравствуйте, sergey2b, Вы писали:

S>скажем добавили новый метод

Куда добавили? Модификация приватного кода отлично дружит с идеомой PImpl. Если же метод добавляется в публичную секцию, то перекомпилировать придётся всё.
Например, добавление виртуальной функции поменяет структуру vtable и поэтому нужно перекомпилировать весь код, который заглядывает внутрь vtable. Аналогично, и при других модификациях перекомпиляция может быть необходима, а не объясняться лишь тем, что в C++ в определении класса перемешаны существенные и неважные для пользователя подробности.

S>как надо организовать использование класса A

Варианты:
1. Использовать PImpl;
2. Завести наследников и модифицировать их, а не A;
3. Смирится и постараться модифицировать A реже чтобы минимизировать ущерб.
Re: как использовать класс
От: kov_serg Россия  
Дата: 03.02.17 13:28
Оценка: +1
Здравствуйте, sergey2b, Вы писали:

S>Подскажите пожалуйста как ответить на такой вопрос


S>имееться определение класса A

S>который используеться в 16 Gb кода
// h
struct A {  // interface
  virtual ~A() {}
  virtual int dispatch(int id,void* args)=0;
  virtual void fn1()=0;
  ...
  virtual void fn100500()=0;
};

...
// dynamic lib
struct A1 : A {
  ...
  virtual void fn100501() {};
};
A* create_A() { return new A1(); }

S>как надо организовать использование класса A так что бы
S>изменение его определение (скажем добавили новый метод) не вызывало полной перекомпиляции используещего его кода
Если кол-во методов меняется используй динамическую диспечеризацию вызовов + методы для получения информации об их наличии типа IDispatch
Отредактировано 03.02.2017 13:34 kov_serg . Предыдущая версия .
Re: как использовать класс
От: Pzz Россия https://github.com/alexpevzner
Дата: 03.02.17 14:00
Оценка:
Здравствуйте, sergey2b, Вы писали:

S>как надо организовать использование класса A так что бы

S>изменение его определение (скажем добавили новый метод) не вызывало полной перекомпиляции используещего его кода

Мне кажется, лучше этого не делать. Потому что если это сделать (через какую-нибудь обертку, к примеру), то получится конструкция, в которой 16 Gb кода используют некий класс, не видя его декларацию. И если когда-нибудь что-нибудь разъедется между классом, и тем, что 16 Gb кода об нем думают, то искать возникающие случайные ошибки придется по всему этому объему кода. Бррр, лучше иногда стерпеть его перекомпиляцию...
Re[2]: как использовать класс
От: kov_serg Россия  
Дата: 03.02.17 14:12
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, sergey2b, Вы писали:


S>>как надо организовать использование класса A так что бы

S>>изменение его определение (скажем добавили новый метод) не вызывало полной перекомпиляции используещего его кода

Pzz>Мне кажется, лучше этого не делать. Потому что если это сделать (через какую-нибудь обертку, к примеру), то получится конструкция, в которой 16 Gb кода используют некий класс, не видя его декларацию. И если когда-нибудь что-нибудь разъедется между классом, и тем, что 16 Gb кода об нем думают, то искать возникающие случайные ошибки придется по всему этому объему кода. Бррр, лучше иногда стерпеть его перекомпиляцию...

Вы же используете плагины без перекомпиляции тех кто их использует и ничего.
Отредактировано 03.02.2017 14:13 kov_serg . Предыдущая версия .
Re: как использовать класс
От: c-smile Канада http://terrainformatica.com
Дата: 03.02.17 23:43
Оценка:
Здравствуйте, sergey2b, Вы писали:


S>как надо организовать использование класса A так что бы


Другими словами вопрос формулируется так: какие пути достижения stable ABI?

1. Внешние функции, а не методы:
class A {...};

void foo(A* pa)


2. Использование интерфейсов в стиле COM:

component.h
class Component: IUnknown {
  ...
  HRESULT GetInterface(iid, IUnknown** p);
  
  virtual void Foo() {...}
};


component2.h

class ComponentV2: public Component {
  ...

  virtual void Bar() {...}
};


Т.е. component.h не меняется. А тем кому нужна новая функциональность делают #include "component2.h"
Re: как использовать класс
От: MasterZiv СССР  
Дата: 08.02.17 09:53
Оценка:
Здравствуйте, sergey2b, Вы писали:

S>имееться определение класса A

S>который используеться в 16 Gb кода

S>как надо организовать использование класса A так что бы

S>изменение его определение (скажем добавили новый метод) не вызывало полной перекомпиляции используещего его кода

В виде интерфейса (паттерн Bridge).
Чтобы изменение его определение (добавление метода) не вызывало полной перекомпиляции используещего его кода, нужно
также ещё наследовать интерфейсы, по версиям полного интерфейса (примерно так делается в COM),т.е.
базовый интерфейс -- версия 1, добавляются методы -- наследуется от базового интерфейса интерфейс версии 2,
туда добавляются новые методы. Весь код, который не использует новые методы, не нужно пересобирать даже, не
то, что перекомпилировать (бинарная совместимость), а код, использующий новые методы, будет вынужден заменить
интерфейс базовой версии на новую версию, и вынужден будет пересобраться.
Отредактировано 08.02.2017 9:58 MasterZiv . Предыдущая версия .
Re: как использовать класс
От: rg45 СССР  
Дата: 08.02.17 10:27
Оценка:
Здравствуйте, sergey2b, Вы писали:

S>имееться определение класса A

S>который используеться в 16 Gb кода
S>как надо организовать использование класса A так что бы
S>изменение его определение (скажем добавили новый метод) не вызывало полной перекомпиляции используещего его кода

Предположу, что от тебя хотели услышать рассказ об идеоме pImpl, абстракных интерфейсах, вероятно также, о структурных паттернах: Адаптор, Декоратор, Фасад и др.

А вообще, изменения изменениям рознь — одно дело, когда меняются детали реализации класса, другое — когда открытый интерфейс.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re: как использовать класс
От: alzt  
Дата: 09.02.17 07:53
Оценка: +1
Здравствуйте, sergey2b, Вы писали:

S>имееться определение класса A

S>который используеться в 16 Gb кода

S>как надо организовать использование класса A так что бы

S>изменение его определение (скажем добавили новый метод) не вызывало полной перекомпиляции используещего его кода

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

Типа:
A.h:
class A;

class B {
public:
    void useIt(const A& a)const;
};


SmallFile.cpp:
void B::useIt(const A& a)const {
    int r = a.op2074() + a.op34879(7);
    a.op45(r+2);
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.