Singleton done right in C++ 11

Today searching the internet I’ve found a “cool” and simple method to create a safe singleton that performs well in multithreading environment.

With a small amount of lines you can achieve both: safe initialization and multithreading safety.

class Singleton {
     static std::once_flag onceFlag;
     static Singleton* instance;
public:
     static Singleton& getInstance(){
          std::call_once(onceFlag, []{
               instance = new Singleton();
          });
          return *instance;
     }

private:
     Singleton(){};
}

 

As c++ documentation says the:

  • The class std::once_flag is a helper structure for std::call_once.
    An object of type std::once_flag that is passed to multiple calls to std::call_once allows those calls to coordinate with each other such that only one of the calls will actually run to completion.
    std::once_flag is neither copyable nor movable.
  • The std::call_once executes the Callable object f exactly once, even if called from several threads.

 

Having this in mind stay save and use singleton in a safe way!

Happy coding!

The PIMPL idiom

The purpose

Remove compilation dependencies on internal class implementations and improve compile times.

The story behind

When a header file changes, any files that #include that file will need to be recompiled. In the case of a class header, this is true even if those changes only apply to private members of the class. The PIMPL idiom hides private members from any users of the header file, allowing these internal details to change without requiring recompilation of the client code.

Lines 5–17 define a class, foo, to which we have applied the PIMPL idiom. This class definition includes only the public interface of the class and a pointer to the internal implementation. We use a std::unique_ptr (line 16) to ensure the lifetime of the implementation is managed correctly, which we initialise in foos constructor (line 35).

While the internal implementation class, impl, is declared in the header file on line 15, its definition appears in the implementation file on lines 22–32. This allows the class definition to change without requiring users of foo to recompile.

We have explicitly defaulted foo’s destructor on line 40, which is necessary because the destructor needs to be able to see the complete definition of impl (in order to destroy the std::unique_ptr). Note that we have also explicitly defaulted the move constructor and assignment operator on lines 42–43 so that foo can be moved. To make foo copyable, we must also implement the copy constructor and assignment operator.

Note: std::make_unique was introduced in C++14. For C++11, you can roll your own implementation.

 

Brief example

// foo.h - header file
#include <memory>
class foo
{
    public:
        foo();
        ~foo();
        foo(foo&&);
        foo& operator=(foo&&);
    private:
        class impl;
        std::unique_ptr pimpl;
};
// foo.cpp - implementation file
class foo::impl
{
    public:
        void do_internal_work()
        {
            internal_data = 5;
        }
    private:
        int internal_data = 0;
};
foo::foo()
    : pimpl{std::make_unique()}
{
    pimpl->do_internal_work();
}
foo::~foo() = default;
foo::foo(foo&&) = default;
foo& foo::operator=(foo&&) = default;

 

Inheritance in C++

The question:

I looked and couldn’t find a good explanation of the difference between public, private, and protected inheritance in C++. All of the questions I’ve found deal with specific cases. What is the difference in general?

The answer:

There are three accessors that I’m aware of: public, protected and private.

Lets take the following example:

class Base {
    public:
        int publicMember;
    protected:
        int protectedMember;
    private:
        int privateMember;
};

Everything that is aware of Base is also aware that Base contains publicMember. Only the children (and their children) are aware that Base contains protectedMember. No one but Base is aware of privateMember. By is aware of, I mean acknowledge the existence of, and thus be able to access.

The same happens with public, private and protected inheritance. Let’s consider a class Base and a class Child that inherits from Base.

  • If the inheritance is public, everything that is aware of Base and Child is also aware that Child inherits from Base.
  • If the inheritance is protected, only Child, and its children, are aware that they inherit from Base.
  • If the inheritance is private, no one other than Child is aware of the inheritance.

Testarea unui singleton folosind Mock Object

Problema

De multe ori testarea singleton-urilor este una foarte anevoioasa. Folosirea acestui pattern pe langa ca aduce multa simplitate in ceea ce priveste accesul la variabilele protejate de singleton ingreuneaza testarea codului.

Urmatorul cod prezinta solutia clasica, si nu neaparat cea mai buna, de implementare a unui singleton:


class Singleton
{
  public:
    static Singleton* getInstance()
    {
       if (!instance)
       {
          instance = new Singleton;
       }
       return instance;
    }

  private:
    Singleton(){}
    static Singleton* instance;
};

Pentru a utiliza acest singleton in cadrul altor clase avem de facut fie Singleton::getInstance() sau folosind tehnica de Dependency Injection. Continue…

Factory Method Design Pattern

Dupa singleton, un alt pattern destul de des folosit in crearea obiectelor este cel denumit “factory method”. Pe scurt acesta izoleaza partea de creare si parametrizare a unui obiect intr-o metoda statica ce are rolul, initial, de a crea obiectul iar mai apoi de a-l parametriza facandu-l gata pentru a fi utilizat. Continue…

Singleton Pattern

Singleton sau “instanta unica” este un design pattern creational. Acesta constrange numarul obiectelor pe care o clasa le defineste. Singleton-ul este frecvent intalnit la definirea accesului la resurse “unice” in sistem precum:

  • baze de date
  • resurse hardware (registri, componente harware: modem, gps, gprs …)

Continue…

Normalizare baza de date

Dupa aproape 4 ani revin asupra acestui subiect pentru ca e clar ridica probleme in randul incepatorilor ce au de a face cu bazele de date. Spun incepatori deoarece sincer, eu nu mai folosesc aceasta metoda de mormalizare lucrurile venind de la sine.

Un exemplu de normalizare il gasiti aici: exemplu normalizare baza de date abonati telefonici

Iata scenariul:

Sa se proiecteze o baza de date pentru o organizatie, avand in vedere urmatoarele constrangeri: – constrangerea de integritate a entitatii; – constrangerea de integritate referentiala; – baza de date contine cel putin 6 tabele; – baza de date contine cel putin un tabel referential (entitate referentiala transversala).

Normalizarea se va face pe baza primelor 3 forme normale. Dupa proiectare, trebuie realizata diagrama entitate-asociere utilizand aplicatia MySQL Workbench, precum si scriptul SQL care implementeaza baza de date.

Sa se implementeze o operatie de tip JOIN pe trei tabele, care sa utilizeze cel putin o functie de sumarizare si sa contina cel putin o filtrare. Sa se implememnteze o vizualizare avand la baza o operatie de tip JOIN (diferita de cea precizata la punctul anterior).

Cum gandim si ce facem de aici:
In primul rand trebuie sa plecam de la ideea centrala pentru care dorim normalizarea.

De exemplu pentru o ferma cu animale sa zicem ca vrem sa tinem minte ce vaccinari ii sunt facute unui animal dealungul vietii. Pentru asta in baza de date vom aveam nevoie de date de identificare pentru animal, date de identificare pentru vaccin, date de identificare pentru cel ce a facut vaccinul, nu?

Pasul 1

bazaAnimale(idAnimal, numeAnimal, varstaAnimal, tipAnimal, idMedicIngrijitor, numeMedicIngrijitor, telefonMedicIngrijitor, idVaccin, numeVaccin, dozaVaccin, tarifDoza)

Pasul 2

Aici incepe pur si simplu normalizarea.

Procesul de normalizare consta in “spargerea” acestei baza de date in tabele astfel incat informatia gazduita in sistem sa fie minimala. (De ce sa avem un spatiu ocupat de 2Mb cand putem avea 1.5Mb?, nu?)

  • De exemplu mai multe animale pot sa aiba acelasi ingrijitor: nu ar fi mai util ca ingrijitorul la care se face referire sa fie identificat printr-un numar? (nu vom mai avea ceva de genul: animal 1, 10 ani, porc cu ingrijitorul Popescu Ion 0700 000 000 ci vom sti ca ingrijitorul x (x – un numar) este popescu ion si astfel vom rezolva mult mai usor situatiile in care acesta sa zicem is modifica numarul de telefon.
  • Un alt exemplu similar cu cel de sus este faptul ca unui animal ii pot fi facute o serie de vaccinuri. Dintre acestea o parte ii sunt administrate si unui al animal.

Procesul de nomalizare presupune mai multe etape, etape ce face ca Bazei de date normalizate sa ii fie aplicate mai multi algorimti de “simplicare” numiti si FORME NORMALE (NORMAL FORMS).

Acestea sunt:

  • Forma normala 1 – care elimina grupurile repetitive
  • Forma normala 2 – in urma careia dependintele fata de cheia primara a tabelului sunt “totale” (vom sti cu siguranta ca elementul x din tabela T nu va fi putea fi confundat cu y).
  • Forma normala 3 – eleminarea redundantei datelor (daca intr-un tabel va trebui sa specificam pretul unui produs aferent unui anumit gramaj nu are rost sa facem acest lucru pentru fiecare element din tabel. Mai bine vom stoca pretul/gramaj intr-un alt tabel si ne vom referi la pret doar prin gramaj)

Mersul algoritmului este urmatorul:

1  Strucutra de baza

Structura de baza a bazei de date este redata de relatia de mai jos:

bazaAnimale(idAnimal, numeAnimal, varstaAnimal, tipAnimal, idMedicIngrijitor, numeMedicIngrijitor, telefonMedicIngrijitor, idVaccin, numeVaccin, dozaVaccin, tarifDoza)

2  Normalizare

Eliminarea grupurilor repetitive prin aplicarea formei normale 1 (1NF).

Prin aplicarea 1NF vom aveam urmatoarele tabele:

  • Animal(idAnimal, numeAnimal, varstaAnimal, tipAnimal)
  • MediciIngrijitori(idAnimal, idMedicIngrijitor, numeMedicIngrijitor, telefonMedicIngrijitor, idVaccin, numeVaccin, dozaVaccin, tarifDoza)

Deasemenea se observa existenta unui grup repetitiv si in cadrul relatiei Ingrijtor: pentru un medic ingrijitor putem avea mai multe vaccinuri efectuate pentru diverse animale.

Vom aplica asadar dinnou forma normala 1 (1NF) asupra relatiei MedicIngrijitor si vom obtine urmatoarele 2 tabele: MediciIngrijitori, Vaccinuri.

  • MediciIngjitori(idAnimal, idMedicIngrijitor, numeMedicIngrijitor, telefonMedicIngrijitor)
  • Vaccinuri(idAnimal, idMedicIngrijitor, numeVaccin, dozaVaccin, tarifDoza)

In urma acestei etape de normalizare deci vom obtine tabelele: Animal, MediciIngrijitori, Vaccinuri.

Observam in continuare inexistenta dependentelor totale fata de cheia primara a relatiei pentru tabelele MediciIngrijitori, Vaccinuri iar in consecinta procedam prin aplicarea 2NF. Vom obtine:

  • MediciIngjitori(idMedicIngrijitor, numeMedicIngrijitor, telefonMedicIngrijitor)
  • AnimalMedicIngrijitor(idAnimalidMedicIngrijitor)
  • Vaccinuri(idVaccin, numeVaccin, dozaVaccin, tarifDoza)
  • VaccinuriAnimal(idVaccinidAnimal)

Se observa in ca o problema in ceea ce priveste redundanta datelor si anume existenta unei relatii de tipul Many : One si anume aceea prezentata de idVaccin respectiv tarifDoza.Stim ca in functie de doza administrata avem un anumit tarif pentru vaccinul efectuat. Astfel pentru eliminarea aceste dependente tranzitive vom proceda prin aplicarea formei normal 3 (3NF):

  • Vaccinuri(idVaccin, numeVaccin, dozaVaccin) *unde dozaVaccin este cheie externa
  • TarifareVaccinuri(dozaVaccin, tarifDoza)

3  Structura finala a bazei de date

In urma pocesului de normalizare a bazei de date initiale au rezultat urmatoarele relatii(tabele) ce definesc structura bazei de date pentru managementul vaccinarilor animalelor din cadrul unei Ferme.

  • Animal(idAnimal, numeAnimal, varstaAnimal, tipAnimal)
  • MediciIngjitori(idMedicIngrijitor, numeMedicIngrijitor, telefonMedicIngrijitor)
  • AnimalMedicIngrijitor(idAnimalidMedicIngrijitor)
  • Vaccinuri(idVaccin, numeVaccin, dozaVaccin)
  • VaccinuriAnimal(idVaccinidAnimal)
  • TarifareVaccinuri(dozaVaccin, tarifDoza)