2017-07-12 2 views
-1

Je suis en train d'écrire un wrapper pour un certain c api, en particulier autour d'une paire de fonctions qui prennent cette forme:Emballage C dans RAII sans exposer les types

int add_list_a(ablist *l, int id); 
int add_list_b(ablist *l, long id); 

Ce que je voudrais faire est cacher la différence entre ces deux et quelque chose comme ceci:

class List 
{ 
    void addAB(AB *ab); 
}; 

class AB {}; 
class A: public AB {int id;}; 
class B: public AB {long id;}; 

Je préfère ne pas directement pointeurs mis directement dans l'interface public qui rendrait l'interface dépendra de boost :: shared_ptr. (Je ne peux pas utiliser C++ moderne)

Je me suis alors rendu compte qu'il était difficile de définir des classes qui n'avaient pas besoin d'être enveloppées dans un pointeur intelligent et qui n'exposaient pas certains composants internes pour que cela fonctionne bien.

je peux faire quelque chose comme ceci:

class List 
{ 
private: 
    ablist *l; 
public: 
    void addAB(AB ab) { 
    ab.addToList(l); 
    } 
}; 

class AB { 
private: 
    boost::shared_ptr<InternalAB> ab; 
public: 
    void addToList(list *l) { 
    ab->addToList(l); 
    } 
}; 

class InternalAB { virtual void addToList(list *l) = 0; } 

avec ces types en interne:

class InternalA: public InternalAB { 
public: 
    int id; 
    void addToList(list *l) 
    { 
    add_list_a(l, id); 
    } 

}; 
class InternalB: public InternalAB { 
public: 
    long id; 
    void addToList(list *l) 
    { 
    add_list_b(l, id); 
    } 
}; 

, mais il est assez alambiquée et encore addToList expose().
A et B sont créés à partir de fonctions statiques, donc leur initialisation n'est pas un problème, ils ont beaucoup de code commun dans mon cas, c'est pourquoi je voudrais garder un type commun entre eux.
Y a-t-il une meilleure façon de faire cela? Je pourrais avoir manqué quelque chose de tout mais il est un peu un cas particulier et je ne peux pas trouver quelque chose de semblable

+2

Je ne suis pas certain de comprendre votre problème, mais qu'est-ce qui ne va pas avec une seule classe fournissant les deux surcharges qui appellent en interne la fonction C correspondante sur votre membre privé? –

+0

tbh Je ne comprends pas ce que vous obtenez du code qui suit le "Je peux faire quelque chose comme ça:". Aussi je ne comprends pas cela "Je ne préfère pas directement placer des pointeurs directement dans l'interface publique car cela rendrait l'interface dépendante de boost :: shared_ptr" Si l'interface publique demande des pointeurs bruts alors pourquoi boost :: shared_ptr est-il pertinent? – user463035818

+0

Je pense que ce que vous cherchez est une révision de code. Il ya un forum pour cela https://codereview.stackexchange.com/ – Pumkko

Répondre

0

Voici votre solution aussi proche de ce que vous avez écrit dans votre exemple possible:

class AB { 
    friend List; 
protected: 
    virtual void addToList(ablist* list) = 0; 
}; 

class A : private AB { 
    void addToList(ablist* list) override { add_list_a(list, id); } 
    int id; 
}; 

class B : private AB { 
    void addToList(ablist* list) override { add_list_b(list, id); } 
    long id; 
}; 

class List { 
    ablist* l; 

public: 
    void add(AB* ab) { 
     ab->addToList(l); 
    } 
}; 

uniquement accessible La fonction à appeler est List :: add. La classe List entoure la structure ablist et les classes A et B sont basées sur celles de votre exemple.