2015-06-26 3 views
0

Я работал над существующим куском кода C++, который вызывает базовые функции C. Текущий код уже работает отлично, но мне нужно сделать несколько новых аргументов и использовать эти новые аргументы для изменения некоторых типов поведения. Идея демонстрируется ниже код:Как добавить новый аргумент в существующий код в C?

// this is how the existing works look like without my changes: 
    do_something_case1(int p1, double p2, struct1* p3, ...) 
    { 
     ... // do a lot of things 

     // my work is to give client ability to override config1, config2 
     // with their own structures. 
     // get_config1() and get_config2() are existing pre-defined 
     // configurations and are used extensively elsewhere. 

     ConfigStruct1 config1 = get_config1(...); 
     ... // do a lot of things 
     ConfigStruct2 config2 = get_config2(...); 
     ... // do something 
     foo(config1, config2, ...); 
     ... // more code 
    } 

    do_something_case2(int p1, double p2, struct1* p3, ...) 
    { 
     // in a similar situation as do_something_case1 
    } 

    ... // more do_something_case3, do_something_case4 defined here 

    // this function needs to take client overrides. 
    void do_something(int p1, double p2, struct1* p3, ...) 
    { 
     if(case1) 
     { 
      do_something_case1(p1, p2, p3, ...); 
     } 
     else if(case2) 
     { 
      do_something_case2(p1, p2, p3, ...); 
     } 
     else if(case3) 
     { 
      do_something_case3(p1, ...); 
     } 
     else if(...) // more if statements to come 
     { 
      ... // do something 
     } 
    } 

Моя работа, чтобы дать возможность клиенту использовать свой собственный ConfigStruct. В принципе ConfigStruct1, ConfigStruct2 должен быть входом вместо того, чтобы быть решенным в функции, которая не дает клиенту большую свободу их переопределения. Однако этот код очень старый и широко используется в системе, и я не хочу нарушать существующий клиентский код. И я определенно хочу воспользоваться всеми остальными сложными логиками, которые уже определены в этих функциях do_something_case(). Если бы это было C++, я мог бы просто добавить новый аргумент, который принимает значение по умолчанию,

// if it were C++, I could do: 
    do_something_case1(int p1, double p2, struct1* p3, ..., 
         ConfigStruct1* pConfig1=NULL, 
         ConfigStruct2* pConfig2=NULL) 
    { 
     if(NULL == pConfig1) 
     { 
      // call get_config1(..) 
     } 
    } 

или использовать перегрузку функции. Но так как C тоже не поддерживает, я чувствую, что я застрял с меньшими и уродливыми вариантами. Один из способов решения этой проблемы - скопировать и вставить все эти функции и сделать хирургические изменения в новых. Это сделает его еще более уродливым. Есть ли у вас какие-либо предложения по оказанию помощи в моей ситуации?

спасибо.

+0

Вы не можете иметь функции с одинаковыми именами с C, вы можете играть с указателем, если вам нужно объектно-ориентированное программирование ... – Proxytype

+0

Я не возражаю, если в этом случае это не объектно-ориентированное программирование, но я надеюсь, что получаю решение, достойное и не вызывающее больше хлопот в будущем. – dhu

+0

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

ответ

1

Если это C++, я мог бы просто добавить новый аргумент, который принимает значение по умолчанию

Только если вы были готовы и способны перекомпилировать все которое использует эту функцию. Похоже, это может быть большой проблемой, и, возможно, даже не жизнеспособной. В C++ гораздо больше дыма & зеркал, чем есть реальная магия.

[...] или использовать функцию перегрузки.

Перегруженные функции C++ связаны рано - или, по крайней мере, определенная перегруженная сигнатура, используемая в любом конкретном вызове, выбирается во время компиляции. Поэтому просто добавить перегруженную версию было бы недостаточно для того, чтобы существующий код вызывал новую версию. Вместо этого вам нужно будет перекомпилировать все. Дым, зеркала, без магии.

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

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

Смежные вопросы