C++

From APIDesign

Revision as of 07:02, 27 September 2012 by JaroslavTulach (Talk | contribs)
Jump to: navigation, search

C++ is a language that tried (since 1979) to bring OOP concepts into C. Wikipedia definition says it is multi-paradigm - I can agree with that, the C++ languages offers almost any possible concept that has appeared since 1979. That may be very pleasant when you are writing your code, but slightly problematic when you or your team peer try to read that code few years later. Java original syntax was heavily influenced by C++ - just a lot of paradigms were luckily left out.

Encapsulation and Performance in C++

I've noticed an interesting article describing why C is more effective than C++ and in general most of OOP languages. The article claims that by using OOP and insisting on encapsulation one cannot implement linked list as effectively as in C. I sort of agreed, but then I found that by using trait in Scala one can implement effective list while keeping encapsulation.

Not a long time after that a reader subscribed as jtulach (stands for Jirka Tulach probably - as I am not aware of any other Tulach who would observe my blogs, could spell C++ and who's name would start with J) argued and proved that one can achieve the same in C++. Here is jtulach's final code snippet:

template<class ITEM>
class llist {
  protected:
        ITEM *first;
  public:
	void add(ITEM& p)
        {
          p.prev=NULL;
          p.next=first;
          first=&p;
        }
	void remove(ITEM& p)
        {
          ITEM *pr=p.prev;
          ITEM *nx=p.next;
          if(pr) pr->next=nx;
          else first=nx;
          if(nx) nx->prev=pr;
        }
 
        ITEM *get(int idx)
        {
          ITEM *i=first;
          while((i)&&(idx-->0))
            i=i->next;
 
          return i;
        }
 
        llist(void) { first=NULL; };
        ~llist() { };
};
 
// not inherited, requires to define next and prev properties
class person_item  {
  private:
    friend llist <person_item>;
    person_item* next;
    person_item* prev;
  protected:
    int age;
    const char* name;
 
  public:
    person_item (int age, const char* name) { this->age=age; this->name=name; }
};
 
 
template<class ITEM>
class ll_item  {
  friend llist <ITEM>;
private:
  ITEM* next;
  ITEM* prev;
};
 
// inherited from ll_item template which defines next and prev for me
class animal_item : public ll_item <animal_item>{
  protected:
  const char* name;
 
  public:
 
  animal_item(const char* name) : ll_item <animal_item>() { this->name=name; }
};
 
int main(int argc, char* argv[])
{
  person_item a(10, "Ben");
  person_item b(20, "Nora");
  person_item c(30, "John");
 
  animal_item x("Fifi");
  animal_item y("Bobika");
  animal_item z("Bill");
 
  llist <person_item> persons;
  persons.add(b);
  persons.add(c);
  persons.add(a);
//  persons.add(x); - compilation fails
 
  llist <animal_item> animals;
  animals.add(x);
  animals.add(y);
  animals.add(z);
}

--jtulach 14:04, 17 September 2012 (CEST)


I especially like the choice between inheriting from ll_item as in case of animal_item or defining the next and prev fields directly as in case of people_item. At the end it seems C++ is not as bad as originally thought. It can be as performant as C while keeping the OOP like-encapsulation.

Personal tools
buy