ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
13 июля
490233 Топик полностью
fk0, легенда (21.02.2014 21:51 - 21:57, просмотров: 53) ответил Хитрый Китаец на Не вызывайте зависимый объект явно, передайте именно ссылку на него, не указатель, при создании объекта как параметр и сохраните. Вероятность забывания резко снизится.
C++ нет. В C что-то такое тоже можно сделать. "Фабрику классов", возвращающую структуры (пустые, не важно, важно что для C они все разные) и вызывающую конструктор нужного типа объекта (причём сразу и синглетон делает):  #include <stdio.h> #include <stdbool.h> /* A is independed */ void init_A(void) { puts("A constructed."); } void use_A(void) { puts("A used."); } typedef struct {} type_A; type_A make_A(void) { static bool once=0; if (!once) init_A(), once=1; return (type_A) {}; } /* B is depended from A */ void init_B(void) { use_A(); puts("B constructed."); } void use_B(void) { puts("B used."); } typedef struct {} type_B; type_B make_B(type_A refA) { static bool once=0; (void)refA; if (!once) init_B(), once=1; return (type_B) {}; } /* C using A and B */ void init_C() { use_B(); use_A(); puts("C constructed."); } void use_C() { puts("C used."); } typedef struct {} type_C; type_C make_C(type_A refA, type_B refB) { static bool once=0; (void)refA, (void)refB; if (!once) init_C(), once=1; return (type_C) {}; } /* top level */ int main() { #if 0 make_A(); make_B(make_A()); make_C(make_A(), make_B(make_A())); #else make_C(make_A(), make_B(make_A())); make_B(make_A()); make_A(); // make_B(make_B(make_A())); // gives error because of type cheking #endif return 0; } И значит очередной конструктор должен вызываться не просто так (void), а со списком этих стуктур в аргументе. А кто его вызывал (на самом верхем уровне получается) должен озаботиться вызовом "фабрики". Забыть сложно (если не руками struct написать), невозможно. Здорово, но. С чем боролись (со списком кого и в каком порядке вызывать) -- на то и напоролись! В функции main. Строчки в списке переставлять, конечно, теперь можно. Список теперь в аргументах make_XXX(...) И если я хочу исключить какой-то *.o из программы -- это ж я должен и строчки эти редактировать (разумеется, ничего не должно зависеть от исключаемого _в_ _итоге_, но зависимости между несколькими исключаемыми модулями могут быть сложные). И верхний уровнеь должен знать кто от кого зависит. Это вообще не логично! Сам модуль ещё может знать, но не верхний уровень. Его что, теперь править после каждой правки модуля? Антиархитектура какая-то. Или я не догоняю и make_A, например, можно написать в самом A? И каждый модуль экспортирует свой make_XXX ? Да, как я понял, в C++ реализации я не должен напрямую вызывать, а использовать refA, refB и т.п. В C, не совсем понятно как быть... Структуры с указателями на функции целиком передавать неудобно. А почему не указатели на структуры? Там ж тип тоже проверяется. Сами структуры внутри модулей (static) спрятать, только чтоб через фабрику.
[ZX]