Etichete: nicio etichetă

Înlănțuire

Înlănțuirea metodelor (method chaining) este un stil de programare ce poate fi utilizat în contextul programării orientate pe obiecte. Constă în faptul că metodele vor avea ca rezultat obiecte. În acest mod apelurile metodelor pot fi înlănțuite într-o singură instrucțiune, evitând declararea unor variabile care să stcheze rezultate intermediare.

Cascadarea

O situație particulară este cascadarea metodelor. Constă în faptul că metodele returnează tocmai obiectul curent (instanța curentă). Astfel apelurile lor sunt înlănțuite, făcând programul ușor de înțeles și evitând “efortul” necesar pentru alegerea unor nume pentru variabile.

Cascadarea metodelor este posibilă în C++ datorită pointerului this – pointer la obiectul curent. Pentru a realiza cascadarea trebuie îndeplinite următoarele:

  • tiplul metodei este referință la clasa curentă;
  • metoda returnează obiectul curent prin dereferențierea pointerului this, adică * this.

Exemple

Operatorul <<

Un exemplu C++ binecunoscut este operatorul de inserție în flux <<, care are ca rezultat obiectul din stânga. Acest fapt permite scrie unei instrucțiuni de forma:

cout << a << " " << b;

Ea este echivalentă cu următoarea secvență:

cout << a;
cout << " ";
cout << b;

sum00

Programul de mai jos este o rezolvare pentru problema #sum00 (suma a două numere):

#include <iostream>

using namespace std;

class T{
    private:
        int a , b;
    public:
        T & Citire(){
            cin >> a >> b;
            return * this;
        }
        T & Suma(){
            cout << a + b;
            return * this;
        }
};

int main()
{
    T().Citire().Suma();
    return 0;
}

Cascadare vs. înlănțuire

Considerăm următoarele două clase:

class A{
    private:
        int n;
    public:
        A & Citire(){
            cin >> n;
            return * this;
        }
        A & Afisare(){
            cout << n << endl;
            return * this;
        }

        A & Dublare(){
            n *= 2;
            return * this;
        }
};

class B{
    private:
        int n;
    public:
        B Citire(){
            cin >> n;
            return * this;
        }
        B Afisare(){
            cout << n << endl;
            return * this;
        }

        B Dublare(){
            n *= 2;
            return * this;
        }
};

Ele diferă doar prin faptul că metodele clasei A returnează însuși obiectul curent, în timp ce metodele clasei B returnează o copie a obiectului curent.

Următoarele două secvențe vor afișa același lucru, deși mecanismele sunt diferite:

Cascadare

A().Citire().Dublare().Afisare();

Înlănțuire (fără cascadare)

B().Citire().Dublare().Afisare();

Diferențele sunt vizibile în următoarele exemple:

Cascadare

A x;
x.Citire().Dublare();
x.Afisare();

Dacă se citește 2, se va afișa 4. Toate apelurile se aplică la același obiect, și anume x.

Înlănțuire (fără cascadare)

B y;
y.Citire().Dublare();
y.Afisare();

Dacă se citește 2, se va afișa 2. Metoda y.Citire() va citi în câmpul n valoarea 2, dar va returna o copie a lui x, asupra căreia se va aplica apelul Dublare(). Se va dubla câmpul n din copie, câmpul n din x râmânând nemodificat!