-1

I'm trying to write a wrapper for a certain c api, specifically around a pair of functions that take this form :

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

What I'd like to do is hide the difference between those two and have something like this :

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

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

I'd rather not directly put pointers directly in the public interface as that would make the interface depend on boost::shared_ptr. (Can't use modern c++)

I then realized it was difficult to define classes that didn't need to be wrapped in a smart pointer and did not expose some internals for this to work well.

I can do something like this :

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; }

with these types internally :

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);
  }
};

but it's pretty convoluted and still exposes addToList().
A and B are created from static functions, so their initialization is not a problem, they have a lot of common code in my case which is why I'd like to keep a common type between them.
Is there a better way to do this ? I might have missed something entirely but it's kind of a specific case and I can't find anything similar

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
  • 2
    Not sure I understand your problem, but what's wrong with just a single class providing the two overloads that internally call the corresponding C function on your private member? –  Jul 12 '17 at 13:08
  • tbh I dont get at all what you gain from the code that follows the "I can do something like this :". Also I dont understand this "I'd rather not directly put pointers directly in the public interface as that would make the interface depend on boost::shared_ptr" If the public interface asks for raw pointers then why is boost::shared_ptr relevant? – 463035818_is_not_an_ai Jul 12 '17 at 13:12
  • I think what you are looking for is a code review. There is a forum for that https://codereview.stackexchange.com/ – Pumkko Jul 12 '17 at 13:12
  • @Pumkko Code Review will not accept this question. – Mast Jul 12 '17 at 13:13
  • @Felix essentially, a or b define given objects in the C api, not just numbers so it's more complicated than that – Strackeror Jul 12 '17 at 13:24
  • Why do you not overload `add` and let them accept both `int` and `long` – Passer By Jul 12 '17 at 13:40

1 Answers1

0

Here is your solution as close to what you wrote in your example as 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);
    }
};

Only accessible function to call is List::add. List class is wrapping the ablist structure and classes A and B are based on the ones from your example.

Maroš Beťko
  • 2,181
  • 2
  • 16
  • 42