
//
// To jest przykładowy kod z podrozdziału 18.5.4 „Problemy ze wskaźnikami” książki
// "Programowanie. Teoria i praktyka z wykorzystaniem C++" Bjarne'a Stroustrupa.
//

//------------------------------------------------------------------------------

class vector {
    int sz;
    double* elem;
    void copy(const vector& arg);                 // Kopiuje elementy z arg do *elem.
public:
    vector(int s) :sz(s), elem(new double[s]) { } // konstruktor
    vector(const vector&) ;                       // Konstruktor kopiujący — definiuje kopiowanie.
    ~vector() { delete[] elem; }                  // destruktor

    int size() const { return sz; }               // aktualny rozmiar

    double get(int n) { return elem[n]; }         // dostęp: odczyt
    void set(int n, double v) { elem[n]=v; }      // dostęp: zapis
    double& operator[](int n) { return elem[n]; } // zwraca referencję
    // ...
};

//------------------------------------------------------------------------------

void fct_that_can_receive_a_0(int* p)
{
    if (p == 0) {
        // robi coś
    }
    else {
        // używanie p
        *p =7;
    }
}

//------------------------------------------------------------------------------

int* fct_that_can_return_a_0()
{
    return 0;
}

//------------------------------------------------------------------------------

// Don't return a pointer to a local variable:
int* f()
{
    int x = 7;
    // ...
    return &x;
}

//------------------------------------------------------------------------------

vector& ff()
{
    vector x(7);
    // ...
    return x;
}    // Usunięcie wektora x.

int main()
{
    // Nie uzyskuj dostępu przez zerowy wskaźnik.
    {
        int* p = 0;
        *p = 7;      // Au!
    }

    int* p = fct_that_can_return_a_0();
    if (p == 0) { 
        // jakieś instrukcje
    }
    else {
        // użycie p
        *p = 7;
    }

    // Inicjuj swoje wskaźniki.
    {
        int* p;
        *p = 9;      // OAu!
    }

    // Nie uzyskuj dostępu do nieistniejących elementów tablic.
    {
        int a[10];
        int* p = &a[10];
        *p = 11;     // Au!
        a[10] = 12;  // Au!
    }

    // Nie uzyskuj dostępu poprzez usunięty wskaźnik.
    {
        int* p = new int(7);
        // ...
        delete p;
        // ...
        *p = 13;     // Au!
    }

    // Nie zwracaj wskaźnika do lokalnej zmiennej.
    {
        int* p = f();
        // ...
        *p = 15;     // Au!

    }

    // Rozważ logicznie ekwiwalentny kod:
    {
        vector& p = ff();
        // ...
        p[4] = 15;     // Au!
    }
}

//------------------------------------------------------------------------------
