Constructori multipli pentru clase in Cpp

Stau acum si fac niste modificari / optimizari intr-un proiect, scris, de sigur, de altcineva. Si, surpriza, ca de fiecare data cand faci review ( caci asta faci inainte de a te apuca sa modifici jumate din codul care e acolo ) gasesti ceva care nu e in regula si care te deranjeaza… ceva atat de mic… dar…

Deci, sa trec la tema. Dupa cum se stie in Cpp se pot defini mai multi constructori, astfel, un exemplu:

class Cluster {
private:
  int a;
  int b;
  int c;
  int d;  //aceasta clasa contine foarte multe variabile interne
public:
  //constructorul creeaza clasa pornind de la alta clasa
  Cluster( CAnotherClass *_class );
  // ctor de copiere
  Cluster( Cluster *_cluster );
  // ctor default
  Cluster( );
};

La prima vedere, acest cod pare nevinovat, dar daca te uiti in implementarea constructorilor, ar arata cam astfel :

Cluster::Cluster( CAnotherClass *_c ) : a( _c->a )
    , b( _c->b )
    , c( _c->c )
    , d( _c ->d )
{ /* no code */ }
Cluster::Cluster( Cluster *_c ) : a( _c->a )
    , b( _c->b )
    , c( _c->c )
    , d( _c ->d )
{ /* no code */ }
Cluster::Cluster( ) : a( 0 )
    , b( 0 )
    , c( 0 )
    , d( 0 )
{ /* no code */ }

in fine, mai pui si constructorul de copiere… si ai 100 de linii de cod cu constructori doar.

Partea nasoala apare doar atunci cand vrei sa adaugi / scoti un membru nou din clasa… ceea ce inseamna ca trebui sa modifici toti constructorii… Poate nu e o problema modificarea constructorilor, dar ce faci daca uiti sa faci modificarile intr-un constructor ( daca ai multe surse se poate intimpla foarte des ).

Pentru a face putin ordine in toti constructorii se procedeaza astfel :
1. se alege o functie ( doar una, posibil privata ) care va avea rolul de a atribui valori membrilor privati

Cluster::set( int a, int b, int c, int d );

2. celalti constructori apeleaza doar functia de set definit la punctul 1.

Cluster::Cluster( CAnotherClass *_c )
{
   set( _c->a, _c->b, _c->c, _c->d );
}
Cluster::Cluster( Cluster *_c )
{
   set( _c->a, _c->b, _c->c, _c->d );
}
Cluster::Cluster( )
{
   set( 0, 0, 0, 0 );
}

Prin o astfel de abordare a problemei aveti doar de castigat din urmatoarele motive:

1. atunci cand adaugi un membru nou in clasa, modifici functia set, iar functiile care folosesc functia set o sa dea eroare la compilare ( compilatorul aici e un ajutor pentru tine, iar in celalalt caz trebuie sa modifici manual in fiecare constructor cu posibilitatea ca poti sa omiti undeva modificarile, compilatorul nu iti da nici o eroare, iar la rulare se poate apela un constructor care nu l-ai update-at si care ti-a lasat noua variabila neinitializata ).

2. daca la un moment dat iti dai seama ca o variabila trebuie tratata mai speciala, sa ii faci nishte prelucrari inainte, atunci acest cod nou o sa il scrii doar in functia de set, nu o sa duplici mai apoi codul in toti constructorii.

3. clasa este mult mai bine structurata si ofera o logica celui care o sa ii face review mai tarziu.

cred ca atat.

poky.ro : intro

Stateam intr-o zi pe un site de torrente… Ma uitam ce mai este nou de download-at, ce se mai poate downloada interesant, poate ceva filme, poate ceva muzica. Ideea e alta, intimplator am dat peste o arhiva destul de mare cu diferite articole in format TXT. Desigur, ca orice om strangator la casa lui, am pus repede la download.

Articolele gasite acolo erau interesante, am citit vreo cateva din curiozitate.

Dupa ce le-am “rasfoit” cat de cat, mi-a venit ideea sa le pun pe net, un loc unde sa aiba toti acces la ele si intr-un final am un proiect ce poate strange trafic datorita continutului.

Si asa, aici se incepe proiectu.

El a fost dezvoltat incremental ( pe pasi mici ), sub forma: problema -> solutie, problema -> solutie

Problema : cum public rapid un articol pe net?

Solutie : o platforma de blog, WordPress ca e free ( si putin experienta prin el ). Am instalat frumos wordpress-ul aici, setat thema, ceva informatii esentiale, pluginul akismet ( antispam pentru commenturi ) si All in One SEO Pack. Si atat, dupa asta am inceput copy+paste si postarea primelor posturi, dupa care puneam categoria, tag-urile ( ceea ce ma obliga sa citesc cam toate articolele care le postam ). Ce e drept, a durat ceva timp pana cand mi-am pus a 2-a problema :

Problema : cum fac sa nu mai fiu nevoit sa citesc toate articolele, si astfel sa maresc viteza cu care fac copy+paste la articole pe blog?

Solutie : Aceasta problema era mai grava pentru tag-uri. Asa ca am inceput sa caut sa vad ce pluginuri sunt pentru setarea automata a tag-urilor. Am gasit un proiect de la yahoo care cica iti tag-uia automat textul si respectiv 1000 de pluginuri pentru wordpress care iti facea legatura dintre blogul tau si serviciul yahoolui. Din pacate, nu stiu de ce, cam nu lucra serviciul ala la mine, poate trebuia sa fac ceva ce trebuia sa stiu sa fac… dar intr-un final nu lucra la mine. Am cautat in continuare. Intru-un final am gasit un plugin TagPiG, un serviciu care integra si utilizarea serviciului de la yahoo, dar si au ei un serviciu propriu de tag-uire a articolelor. Pana la urma am vazut ca asta merge. Are si niste setari interesante. Acum el se ocupa de tag-uirea articolelor, iar eu incepusem sa fac copy+paste la articole mult mai rapid. Si daca totusi tag-uirea se face automat, am renuntat la punerea articolelor in diferite categorii. Doar tag-uri.

PS: N-am zis de ce tag-uirea articolelor este atat de importanta. Ideea esta ca pluginul All in One Seo Pack pune si tag-urile articolului in meta keywords = ceea ce da bine in fata crawlerilor motoarelor de cautare.

Continue reading poky.ro : intro

[linux] generate core dump

Kernelul de linux este capabil de a scri asa numitele “core dump” in caz ca vreo aplicatie “crapa”. Acest dump contine informatii despre starea procesului in momentul cand a crapat. GDB poate citi astfel de dump-uri de core si a scoate informatii utile din el.

Majoritatea distributiilor de linux au aceasta facilitate dezactivata, pentru acestea este nevoie de a activa-o, astfel:

root@srv1:~# ulimit -c unlimited

aceasta comanda va activa crearea de dumpuri pentru shell-ul curent si toate procesele pornite din el. Data viitoare cand va crapa vreo aplicatie, mesajul “Segmentation fault” va fi modificat in “Segmentation fault (core dumped)” si in directoriul curent va fi creat un fisier “core” sau “core.pid” (fisier care si reprezinta core dump-ul).

Dupa ce este generat un fisier core, cu ajutoru gdb-ului se poate afla ce s-a intimplat in aplicatie. GDB se apeleaza :
gdb nume_executabil [core-file]
Cele mai bune informatii puteti sa le scoateti din stacktrace ( lista de functii in care s-a intrat pana la momentul crash-ului ) si deseori aceasta fiind indeajuns de a afla ce nu merge bine. Stacktrace-ul in gdb se afiseaza cu comanda : “bt“.
end.