2016-08-21 3 views
2

Ich habe zwei Funktionen, die sich nur in einem Parameter (unterschiedliche Struktur) unterscheiden, die fast die gleiche Verarbeitung ausführen, was zu viel Codeverdopplung führt. Sehen Sie im folgenden vereinfachten Beispiel:Reduzieren Sie Code-Duplizierung

struct foo { 
    int a; 
}; 

struct bar { 
    int a; 
    int b; 
}; 

foo(struct foo *f) { 
    do_b(); 
    // error handling 
    f->a = 1; 
    do_c(); 
    // error handling 
    do_d(); 
    // error handling 
} 

bar(struct bar *b); { 
    do_a(); 
    // error handling 
    b->b = 2; 
    do_b(); 
    // error handling 
    b->a = 1; 
    do_c(); 
    // error handling 
    do_d(); 
    // error handling 
} 

Gibt es eine intelligente Art und Weise nur eine Funktion bei der Verwendung der Code-Duplizierung zu beseitigen?

+5

Sind Sie bereit, ein 'struct B' auf' struct B {struct A zu ändern; int b; }; '? –

+3

Die wirklich cleveren Möglichkeiten, dies zu tun, erfordern, dass Sie die [strenge Aliasing-Regel] (https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) vollständig verstehen. Leider versteht niemand diese Regel ([Beispiel] (https://stackoverflow.com/questions/39035426/is-aliasing-of-pointers-between-aggregate-c-structs-and-their-members-standards), [ Beispiel] (https://stackoverflow.com/questions/39036857/opaque-structures-with-multiple-definitions), [Beispiel] (https://stackoverflow.com/questions/38968296/a-type-for-arbitrary- Speicher-in-c/38969259 # 38969259)). Du bist also festgefahren. – user3386109

Antwort

4

Ja gibt es, aber nicht in einer Weise, die Sie sich vorstellen. Es ist sehr nützlich, die Typensicherheit zu halten, und es ist nicht in Ihrem besten Interesse, sie loszuwerden (entweder mit Hilfe von Zeigern auf Void oder Struct-Interitance).

Wenn Sie zwei verschiedene Typen haben, die aus einem sinnvollen Grund als separate Typen definiert sind, dann sollten Sie haben zwei separate Funktionen, die diese Typen übernehmen.

Was Sie in diesem Fall tun sollte, ist die Verdoppelung innerhalb dieser Funktionen zu entfernen:

first(int* a) 
{ 
    do_b(); 
    // error handling 
    *a = 1; 
    do_c(); 
    // error handling 
    do_d(); 
    // error handling 
} 

foo(struct foo *f) { 
    first(&f->a); 
} 

bar(struct bar *b); { 
    do_a(); 
    // error handling 
    b->b = 2; 
    first(&b->a); 
} 
Verwandte Themen