---------------
string ident(string arg)        // acuch przekazany przez warto (kopiowany do arg)
{
    return arg;                 // zwrot acucha (przeniesienie wartoci arg poza ident() do wywoujcego)
}

int main ()
{
    string s1 {"Adams"};        // inicjacja acucha (utworzenie w s1).
    s1 = ident(s1);             // skopiowanie s1 do ident()
                                // przeniesienie wyniku ident(s1) do s1;
                                // warto s1 to "Adams".
    string s2 {"Pratchett"};    // inicjacja acucha (utworzenie w s2)
    s1 = s2;                    // skopiowanie wartoci s2 do s1
                                // s1 i s2 maj warto "Pratchett".
}
---------------
class X {
    public:
    X(Jakityp);            // "zwyky konstruktor": tworzy obiekt
    X();                    // konstruktor domylny
    X(const X&);            // konstruktor kopiujcy
    X(X&&);                 // konstruktor przenoszcy
    X& operator=(const X&); // przypisanie kopiujce: czyci cel i kopiuje
    X& operator=(X&&);      // przypisanie przenoszce: czyci cel i przenosi
    ~X();                   // destruktor: robi porzdek
    //...
};
---------------
struct Tracer {
    string mess;
    Tracer(const string& s) :mess{s} { clog << mess; }
    ~Tracer() {clog << "~" << mess; }
};

void f(const vector<int>& v)
{
    Tracer tr {"in f()\n"};
    for (auto x : v) {
        Tracer tr {string{"v loop "}+to<string>(x)+'\n'}; // 25.2.5.1
        //...
    }
}
---------------
f({2,3,5});
---------------
in_f()
v loop 2
~v loop 2
v loop 3
~v loop 3
v loop 5
~v loop 5
~in_f()
---------------
class Vector {
public:
    Vector(int s);
    //...
};
---------------
struct S {
    S();                 // w porzdku
    void S(int);         // bd: konstruktor nie moe mie okrelonego typu
    int S;               // bd: nazwa klasy musi oznacza konstruktor
    enum S { foo, bar }; // bd: nazwa klasy musi oznacza konstruktor
};
---------------
class Vector {
public:
    Vector(int s);
    //...
private:
    double* elem; // elem wskazuje tablic sz liczb typu double
    int sz;      // sz jest liczb nieujemn
};
---------------
Vector::Vector(int s)
{
    if (s<0) throw Bad_size{s};
    sz = s;
    elem = new double[s];
}
---------------
class Vector {
public:
    Vector(int s) :elem{new double[s]}, sz{s} { }; // konstruktor: zajmuje pami
    ~Vector() { delete[] elem; }                   // destruktor: zwalnia pami
    //...
private:
    double* elem;   // elem wskazuje tablic sz liczb typu double
    int sz;         // sz jest liczb nieujemn
};
---------------
Vector* f(int s)
{
    Vector v1(s);
    //...
    return new Vector(s+s);
}

void g(int ss)
{
    Vector* p = f(ss);
    //...
    delete p;
}
---------------
struct S1 {
    string s;
};

S1 x; // OK: x.s zostanie zainicjowana wartoci ""
---------------
struct X { X(int); };

struct S2 {
    Xx;
};

S2 x1;     // bd: brak wartoci dla x1.x
S2 x2 {1}; // OK: x2.x jest zainicjowana wartoci 1
---------------
void C::push_back(const X& a)
{
    //...
    new(p) X{a}; // konstrukcja kopiujca X z wartoci a zapisan pod adresem p
    //...
}
---------------
void C::pop_back()
{
    //...
    p->~X(); // usuwa X pod adresem p
}
---------------
class Nonlocal {
public:
    //...
    void destroy() { delete this; } // jawna destrukcja
private:
    //...
    ~Nonlocal();                    // nie usuwa niejawnie
};

void user()
{
    Nonlocal x;                 // bd: nie mona usun obiektu klasy Nonlocal
    Nonlocal* p = new Nonlocal; // OK
    //...
    delete p;                   // bd: nie mona usun obiektu klasy Nonlocal
    p.destroy();                // OK
}
---------------
class Shape {
public:
    //...
    virtual void draw() = 0;
    virtual ~Shape();
};

class Circle :public Shape {
public:
    //...
    void draw();
    ~Circle(); // przesania ~Shape()
    //...
};
---------------
void user(Shape* p)
{
    p->draw(); // wywouje odpowiedni funkcj draw()
    //...
    delete p;  // wywouje odpowiedni destruktor
};
---------------
int a {1};
char* p {nullptr};
---------------
struct Work {
    string author;
    string name;
    int year;
};

Work s9 { "Beethoven",
          "IX Symfonia d-moll op. 125; Symfonia radoci",
          1824
        };                     // inicjacja po skadowych

Work currently_playing { s9 }; // inicjacja kopiujca
Work none {};                  // domylna inicjacja
---------------
Work alpha;

void f()
{
    Work beta;
    //...
}
---------------
struct Buf {
    int count;
    char buf[16*1024];
};
---------------
Buf buf0;                 // alokowany statycznie, wic inicjowany domylnie

void f()
{
    Buf buf1;             // pozostawia elementy niezainicjowane
    Buf buf2 {};          // naprawd chc wyzerowa te elementy

    int* p1 = new int;    // *p1 jest niezainicjowany
    int* p2 = new int{};  // *p2 == 0
    int* p3 = new int{7}; // *p3 == 7
}
---------------
template<typename T>
class Checked_pointer { // kontroluje dostp do skadowej T*
private:
    T* p;
public:
    T& operator*();     // sprawdza obecno nullptr i zwraca warto
};

Checked_pointer<int> p {new int{7}}; // bd: brak dostpu do p.p
---------------
struct X {
    X(int);
};

X x0;         // bd: brak inicjatora
X x1 {};      // bd: pusty inicjator
X x2 {2};     // OK
X x3 {"dwa"}; // bd: niepoprawny typ inicjatora
X x4 {1,2};   // bd: niepoprawna liczba inicjatorw
X x5 {x4};    // OK: konstruktor kopiujcy jest zdefiniowany niejawnie (17.6)
---------------
struct Y : X {
    X m {0};                 // domylny inicjator dla skadowej X.m w Y
    Y(int a) :X{a}, m{a} { } // inicjacja bazy i skadowej (17.4)
    Y() :X{0} { }            // inicjacja bazy i skadowej
};

X g {1}; // inicjacja zmiennej globalnej

void f(int a)
{
    X def {};              // bd: brak domylnej wartoci dla X
    Y de2 {};              // OK: uycie konstruktora domylnego
    X*p {nullptr};         // inicjacja zmiennej lokalnej
    X var {2};             // inicjacja zmiennej lokalnej
    p = new X{4};          // inicjacja obiektu w pamici wolnej
    X a[] {1,2,3};         // inicjacja elementw tablicy
    vector<X> v {1,2,3,4}; // inicjacja elementw wektora
}
---------------
struct Y : X {
    Xm;
    Y(int a) : X(a), m=a { }; // bd skadni: nie mona uy operatora = do inicjacji skadowej
};

X g(1); // inicjacja zmiennej globalnej

void f(int a)
{
    X def();              // funkcja zwracajca obiekt typu X (niespodzianka!?)
    X* p(nullptr);        // inicjacja zmiennej lokalnej
    X var = 2;            // inicjacja zmiennej lokalnej
    p = new X=4;          // bd skadni: nie mona uy = dla new
    X a[](1,2,3);         // bd: nie mona uy () do inicjacji tablicy
    vector<X> v(1,2,3,4); // bd: nie mona uy () dla listy elementw
}
---------------
struct S {
    S(const char*);
    S(double*);
};

S s1 {"Napier"};        // S::S(const char*)
S s2 {new double{1.0}}; // S::S(double*);
S s3 {nullptr};         // niejednoznaczne: S::S(const char*) czy S::S(double*)?
---------------
struct S1 {
    int a,b; // brak konstruktora
};

struct S2 {
    int a,b;
    S2(int aa = 0, int bb = 0) : a(aa), b(bb) {} // konstruktor
};

S1 x11(1,2);  // bd: brak konstruktora
S1 x12 {1,2}; // OK: inicjacja po skadowych

S1 x13(1);    // bd: brak konstruktora
S1 x14 {1};   // OK: x14.b ma warto 0

S2 x21(1,2);  // OK: uycie konstruktora
S2 x22 {1,2}; // OK: uycie konstruktora

S2 x23(1);    // OK: uycie konstruktora i jednego domylnego argumentu
S2 x24 {1};   // OK: uycie konstruktora i jednego domylnego argumentu
---------------
vector<int> v1 {77}; // jeden element o wartoci 77
vector<int> v2(77);  // 77 elementw o domylnej wartoci 0
---------------
vector<string> v1 {77};      // 77 elementw o domylnej wartoci ""
                             // (vector<string>(std::initializer_list<string>) nie przyjmuje {77})
vector<string> v2(77);       // 77 elementw o domylnej wartoci ""

vector<string> v3 {"Bach!"}; // jeden element o wartoci "Bach!"
vector<string> v4("Bach!");  // bd: brak konstruktora przyjmujcego argument acuchowy

vector<int*> v5 {100,0};     // 100 obiektw typu int* zainicjowanych wartoci nullptr (100 nie jest obiektem typu int*)

vector<int*> v6 {0,0};       // 2 obiekty typu int* zainicjowane wartoci nullptr
vector<int*> v7(0,0);        // pusty wektor (v7.size()==0)
vector<int*> v8;             // pusty wektor (v7.size()==0)
---------------
class Vector {
public:
    Vector(); // konstruktor domylny: brak elementw
    //...
};
---------------
Vector v1;    // OK
Vector v2 {}; // OK
---------------
class String {
public:
    String(const char* p = ""); // konstruktor domylny: pusty acuch
    //...
};

String s1;    // OK
String s2 {}; // OK
---------------
void f()
{
    int a0;              // niezainicjowane
    int a1();            // deklaracja funkcji (zamierzona?)

    int a {};            // a ma warto 0
    double d {};         // d ma warto 0.0
    char* p {};          // p ma warto nullptr

    int* p1 = new int;   // niezainicjowana warto int
    int* p2 = new int{}; // int inicjuje si wartoci 0
}
---------------
template<typename T>
struct Handle {
    T* p;
    Handle(T* pp = new T{}) :p{pp} { }
    //...
};

Handle<int> px; // wygeneruje int{}
---------------
int glob {9};

struct X {
    const int a1 {7}; // OK
    const int a2;     // bd: wymagany konstruktor zdefiniowany przez uytkownika
    const int& r {9}; // OK
    int& r1 {glob};   // OK
    int& r2;          // bd: wymagany konstruktor zdefiniowany przez uytkownika
};
---------------
struct S1 { S1(); };               // ma konstruktor domylny
struct S2 { S2(string); };         // brak konstruktora domylnego

S1 a1[10];                         // OK: 10 domylnych elementw
S2 a2[10];                         // bd: nie mona inicjowa elementw
S2 a3[] { "alpha", "beta" };       // OK: dwa elementy: S2{"alpha"}, S2{"beta"}

vector<S1> v1(10);                 // OK: 10 domylnych elementw
vector<S2> v2(10);                 // bd: nie mona zainicjowa elementw
vector<S2> v3 { "alpha", "beta" }; // OK: dwa elementy: S2{"alpha"}, S2{"beta"}

vector<S2> v2(10,"");              // OK: 10 elementw, kady zainicjowany wartoci S2{""}
vector<S2> v4;                     // OK: brak elementw
---------------
vector<double> v = { 1, 2, 3.456, 99.99 };

list<pair<string,string>> languages = {
    {"Nygaard","Simula"}, {"Richards","BCPL"}, {"Ritchie","C"}
};
---------------
map<vector<string>,vector<int>> years = {
    { {"Maurice","Vincent", "Wilkes"},{1913, 1945, 1951, 1967, 2000} },
    { {"Mar tin", "Richards"}, {1982, 2003, 2007} },
    { {"David", "John", "Wheeler"}, {1927, 1947, 1951, 2004} }
};
---------------
void f(initializer_list<int>);

f({1,2});
f({23,345,4567,56789});
f({});  // pusta lista

f{1,2}; // bd: brak () w wywoaniu funkcji

years.insert({{"Bjarne","Stroustrup"},{1950, 1975, 1985}});
---------------
struct X {
    X(initializer_list<int>);
    X();
    X(int);
};

X x0 {};  // pusta lista: konstruktor domylny czy z list inicjacyjn? (domylny)
X x1 {1}; // jedna liczba cakowita: argument typu int czy jednoelementowa lista? (konstruktor z list inicjacyjn)
---------------
vector<int> v1 {1};     // jeden element
vector<int> v2 {1,2};   // dwa elementy
vector<int> v3 {1,2,3}; // trzy elementy
---------------
vector<string> vs1 {"jeden"};
vector<string> vs2 {"jeden", "dwa"};
vector<string> vs3 {"jeden", "dwa", "trzy"};
---------------
vector<int> v1(1);   // jeden element o domylnej wartoci (0)
vector<int> v2(1,2); // jeden element o wartoci 2
---------------
void f(initializer_list<int> args)
{
    for (int i = 0; i!=args.size(); ++i)
        cout << args.begin()[i] << "\n";
}
---------------
void f(initializer_list<int> args)
{
    for (auto p=args.begin(); p!=args.end(); ++p)
        cout <<*p << "\n";
}
---------------
void f(initializer_list<int> args)
{
    for (auto x : args)
        cout << x << "\n";
}
---------------
int f(std::initializer_list<int> x, int val)
{
    *x.begin() = val;  // bd: prba zmiany wartoci elementu listy inicjacyjnej
    return *x.begin(); // OK
}

void g()
{
    for (int i=0; i!=10; ++i)
        cout << f({1,2,3},i) << '\n';
}
---------------
template<typename E>
class Vector {
public:
    Vector(initializer_list<E> s); // konstruktor z list inicjacyjn
    //...
private:
    int sz;
    E* elem;
};

template<typename E>
Vector::Vector(initializer_list<E> s)
    :sz{s.size()}   // ustawia rozmiar wektora
{
    reserve(sz);    // rezerwuje odpowiedni ilo pamici
    uninitialized_copy(s.begin(), s.end(), elem); // inicjuje elementy w przedziale elem[0:s.size())
}
---------------
vector<vector<double>> vs = {
    {10,11,12,13},               // OK: wektor czterech elementw
    {10},                        // OK: wektor jednego elementu
    10,                          // bd: vector<double>(int) jest jawny

    vector<double>{10,11,12,13}, // OK: wektor czterech elementw
    vector<double>{10},          // OK: wektor jednego elementu o wartoci 10.0
    vector<double>(10)           // OK: wektor 10 elementw o wartoci 0.0
};
---------------
vector<double> v1(7);  // OK: v1 zawiera 7 elementw; uwaga: uycie (), nie {}
vector<double> v2 = 9; // bd: nie mona konwertowa int na vector

void f(const vector<double>&);
void g()
{
    v1 = 9; // bd: nie mona konwertowa int na vector
    f(9);   // bd: nie mona konwertowa int na vector
}
---------------
vector<double> v1 {7};   // OK: v1 zawiera jeden element (o wartoci 7)
vector<double> v2 = {9}; // OK: v2 zawiera jeden element (o wartoci 9)

void f(const vector<double>&);
void g()
{
    v1 = {9}; // OK: teraz v1 zawiera jeden element (o wartoci 9)
    f({9});   // OK: funkcja f jest wywoywana z list {9}
}
---------------
vector<double> v1 {7,8,9};   // OK: v1 zawiera trzy elementy o wartociach {7,8,9}
vector<double> v2 = {9,8,7}; // OK: v2 zawiera trzy elementy o wartociach {9,8,7}
void f(const vector<double>&);
void g()
{
    v1 = {9,10,11};   // OK: v1 zawiera trzy elementy o wartociach {9,10,11}
    f({9,8,7,6,5,4}); // OK: funkcja f jest wywoywana z list {9,8,7,6,5,4}
}
---------------
vector<string> v1 { "Anya"};      // OK: v1 zawiera jeden element (o wartoci "Anya")
vector<string> v2 = {"Courtney"}; // OK: v2 zawiera jeden element (o wartoci "Courtney")

void f(const vector<string>&);
void g()
{
    v1 = {"Gavin"}; // OK: v1 zawiera jeden element (o wartoci "Gavin")
    f({"Norah"});   // OK: funkcja f jest wywoywana z list {"Norah"}
}
---------------
class Club {
    string name;
    vector<string> members;
    vector<string> officers;
    Date founded;
    //...
    Club(const string& n, Date fd);
};
---------------
Club::Club(const string& n, Date fd)
    : name{n}, members{}, officers{}, founded{fd}
{
    //...
}
---------------
Club::Club(const string& n, Date fd)
    : name{n}, founded{fd}
{
    //...
}
---------------
struct B { B(int); /*...*/};
struct BB : B { /*...*/};
struct BBB : BB {
    BBB(int i) : B{i} { } // bd: prba inicjacji bazy bazy
    //...
};
---------------
class X {
    const int i;
    Club cl;
    Club& rc;
    //...
    X(int ii, const string& n, Date d, Club& c) : i{ii}, cl{n,d}, rc{c} { }
};
---------------
class Person {
    string name;
    string address;
    //...
    Person(const Person&);
    Person(const string& n, const string& a);
};

Person::Person(const string& n, const string& a)
    : name{n}
{
    address = a;
}
---------------
class B1 { B1(); };   // ma konstruktor domylny
class B2 { B2(int); } // brak konstruktora domylnego

struct D1 : B1, B2 {
    D1(int i) :B1{}, B2{i} {}
};

struct D2 : B1, B2 {
    D2(int i) :B2{i} {} // B1{} jest uywany niejawnie
};

struct D1 : B1, B2 {
    D1(int i) { }       // bd: B2 wymaga inicjatora typu int
};
---------------
class X {
    int a;
    validate(int x) { if (0<x && x<=max) a=x; else throw Bad_X(x); }
public:
    X(int x) { validate(x); }
    X() { validate(42); }
    X(string s) { int x = to<int>(s); validate(x); } // 25.2.5.1
    //...
};
---------------
class X {
    int a;
public:
    X(int x) { if (0<x && x<=max) a=x; else throw Bad_X(x); }
    X() :X{42} { }
    X(string s) :X{to<int>(s)} { } // 25.2.5.1
    //...
};
---------------
class X {
    int a;
public:
    X(int x) { if (0<x && x<=max) a=x; else throw Bad_X(x); }
    X() :X{42}, a{56} { } // bd
    //...
};
---------------
class X {
    int a;
public:
    X(int x) { if (0<x && x<=max) a=x; else throw Bad_X(x); }
    X() { X{42}; } // prawdopodobnie bd
    //...
};
---------------
class A {
public:
    int a {7};
    int b = 77;
};
---------------
class A {
public:
    int a;
    int b;
    A() : a{7}, b{77} {}
};
---------------
class A {
public:
    A() :a{7}, b{5}, algorithm{"MD5"}, state{"Konstruktor uruchomiono"} {}
    A(int a_val) :a{a_val}, b{5}, algorithm{"MD5"}, state{"Konstruktor uruchomiono"} {}
    A(D d) :a{7}, b{g(d)}, algorithm{"MD5"}, state{"Konstruktor uruchomiono"} {}
    //...
private:
    int a, b;
    HashFunction algorithm; // kryptograficzna funkcja mieszajca dla wszystkich A
    string state;           // acuch okrelajcy stan w cyklu istnienia obiektu
};
---------------
class A {
public:
    A() :a{7}, b{5} {}
    A(int a_val) :a{a_val}, b{5} {}
    A(D d) :a{7}, b{g(d)} {}
    //...
private:
    int a, b;
    HashFunction algorithm {"MD5"};           // kryptograficzna funkcja mieszajca dla wszystkich A
    string state {"Konstruktor uruchomiono"}; // acuch okrelajcy stan w cyklu istnienia obiektu
};
---------------
class A {
public:
    A() {}
    A(int a_val) :a{a_val} {}
    A(D d) :b{g(d)} {}
    //...
private:
    int a {7};                        // 7 dla a oznacza...
    int b {5};                        // 5 dla b oznacza...
    HashFunction algorithm {"MD5"};   // kryptograficzna funkcja mieszajca dla wszystkich A
    string state {"Constructor run"}; // acuch okrelajcy stan w cyklu istnienia obiektu
};
---------------
int count = 0;
int count2 = 0;

int f(int i) { return i+count; }

struct S {
    int m1 {count2};  // tzn. ::count2
    int m2 {f(m1)};   // tzn. this->m1+::count; tzn. ::count2+::count
    S() { ++count2; } // bardzo dziwny konstruktor
};

int main()
{
    S s1; // {0,0}
    ++count;
    S s2; // {1,2}
}
---------------
class Node {
    //...
    static int node_count; // deklaracja
};

int Node::node_count = 0; // definicja
---------------
class Curious {
public:
    static const int c1 = 7;       // OK
    static int c2 = 11;            // bd: nie const
    const int c3 = 13;             // OK, ale nie static (17.4.4)
    static const int c4 = sqrt(9); // bd: inicjator wewntrzklasowy nie jest stay
    static const float c5 = 7.0;   // bd: wewntrzklasowy niecakowitoliczbowy (uyj constexpr zamiast const)
    //...
};
---------------
const int Curious::c1;       // nie powtarzaj tu inicjatora
const int* p = &Curious::c1; // OK: skadowa Curious::c1 zostaa zdefiniowana
---------------
template<typename T, int N>
class Fixed { // tablica o staym rozmiarze
public:
    static constexpr int max = N;
    //...
private:
    T a[max];
};
---------------
class X {
    enum { c1 = 7, c2 = 11, c3 = 13, c4 = 17 };
    //...
};
---------------
template<typename T>
class Matrix {
    array<int,2> dim; // dwa wymiary
    T* elem;          // wskanik do dim[0]*dim[1] elementw typu T
public:
    Matrix(int d1, int d2) :dim{d1,d2}, elem{new T[d1*d2]} {} // uproszczenie (brak obsugi bdw)
    int size() const { return dim[0]*dim[1]; }

    Matrix(const Matrix&);            // konstruktor kopiujcy
    Matrix& operator=(const Matrix&); // przypisanie kopiujce

    Matrix(Matrix&&);            // konstruktor przenoszcy
    Matrix& operator=(Matrix&&); // przypisanie przenoszce

    ~Matrix() { delete[] elem; }
    //...
};
---------------
template<typename T>
Matrix::Matrix(const Matrix& m) // konstruktor kopiujcy
    : dim{m.dim},
    elem{new T[m.size()]}
{
    uninitialized_copy(m.elem,m.elem+m.size(),elem); // kopiuje elementy
}

template<typename T>
Matrix& Matrix::operator=(const Matrix& m) // przypisanie kopiujce
{
    if (dim[0]!=m.dim[0] || dim[1]!=m.dim[1])
        throw runtime_error("Niepoprawny rozmiar w macierzy =");
    copy(m.elem,m.elem+m.size(),elem); // kopiuje elementy
}
---------------
Matrix& Matrix::operator=(const Matrix& m) // przypisanie kopiujce
{
    Matrix tmp {m};  // utworzenie kopii
    swap(tmp,*this); // zamiana reprezentacji tmp z *this
    return *this;
}
---------------
class X {
    string s;
    string s2;
    vector<string> v;

    X(const X& a)       // konstruktor kopiujcy
        :s{a.s}, v{a.v} // pewnie wtpliwe i pewnie niepoprawne
    {
    }
    //...
};
---------------
struct B1 {
    B1();
    B1(const B1&);
    //...
};

struct B2 {
    B2(int);
    B2(const B2&);
    //...
};

struct D : B1, B2 {
    D(int i) :B1{}, B2{i}, m1{}, m2{2*i} {}
    D(const D& a) :B1{a}, B2{a}, m1{a.m1}, m2{a.m2} {}
    B1 m1;
    B2 m2;
};

D d {1};  // konstrukcja z argumentem int
D dd {d}; // konstrukcja z kopiowaniem
---------------
struct S {
    int* p;           // wskanik
};

S x {new int{0}};
void f()
{
    S y {x};          // "kopiuje" x

    *y.p=1;           // zmienia y; wywiera wpyw na x
    *x.p = 2;         // zmienia x; wywiera wpyw na y
    delete y.p;       // wywiera wpyw na x i y
    y.p = new int{3}; // OK: zmienia y; nie ma wpywu na x
    *x.p = 4;         // ups: zapis w dezalokowanej pamici
}
---------------
struct S2 {
    shared_ptr<int> p;
};

S2 x {new int{0}};

void f()
{
    S2 y {x};              // "kopiuje" x

    *y.p=1;                // zmienia y; wywiera wpyw na x
    *x.p = 2;              // zmienia x; wywiera wpyw na y
    y.p.reset(new int{3}); // zmienia y; wywiera wpyw na x
    *x.p = 4;              // zmienia x; wywiera wpyw na y
}
---------------
class Image {
public:
    // ...
    Image(const Image& a);          // konstruktor kopiujcy
    // ...
    void write_block(Descriptor);
    // ...
private:
    Representation* clone();        // kopiuje *rep
    shared_ptr<Representation> rep; // potencjalnie wsplne
};
---------------
Image::Image(const Image& a) // wykonuje kopi pytk
    :rep{a.rep}              // a.rep ma teraz dwch uytkownikw
{
}
---------------
void Image::write_block(Descriptor d)
{
    if (rep.use_count() > 1)
        rep = shared_ptr<Representation>{clone()};
    //... teraz moemy bezpiecznie zapisywa we wasnej kopii rep...
}
---------------
struct Base {
    int b;
    Base(const Base&);
    //...
};

struct Derived : Base {
    int d;
    Derived(const Derived&);
    //...
};

void naive(Base*p)
{
    Base b2 = *p; // moe spowodowa pocicie obiektu: wywouje Base::Base(const Base&)
    //...
}

void user()
{
    Derived d;
    naive(&d);
    Base bb = d; // tnie: wywouje Base::Base(const Base&), nie Derived::Derived(const Derived&)
    //...
}
---------------
template<typename T>
void swap(T& a, T& b)
{
    const T tmp = a; // zapisuje kopi a w tmp
    a=b;             // zapisuje kopi b w a
    b = tmp;         // zapisuje kopi tmp w b
};
---------------
void f(string& s1, string& s2,
    vector<string>& vs1, vector<string>& vs2,
    Matrix& m1, Matrix& m2)
{
    swap(s1,s2);
    swap(vs1,vs2);
    swap(m1,m2);
}
---------------
template<typename T>
class Matrix {
    std::array<int,2> dim;
    T* elem; // wskanik do dim[0]*dim[1] elementw typu T
public:
    Matrix(int d1, int d2) :dim{d1,d2}, elem{new T[d1*d2]} {}
    int size() const { return dim[0]*dim[1]; }

    Matrix(const Matrix&);            // konstruktor kopiujcy
    Matrix(Matrix&&);                 // konstruktor przenoszcy (Matrix&& jest referencj prawostronn; 7.7.2).

    Matrix& operator=(const Matrix&); // przypisanie kopiujce
    Matrix& operator=(Matrix&&);      // przypisanie przenoszce

    ~Matrix() { delete[] elem; }      // destruktor
    //...
};
---------------
template<typename T>
Matrix<T>::Matrix(Matrix&& a) // konstruktor przenoszcy
    :dim{a.dim}, elem{a.elem} // pobranie reprezentacji obiektu a
{
    a.dim = {0,0};            // skasowanie reprezentacji obiektu a
    a.elem = nullptr;
}
---------------
template<typename T>
Matrix<T>& Matrix<T>::operator=(Matrix&& a) // przypisanie przenoszce
{
    swap(dim,a.dim);                        // zamiana reprezentacji
    swap(elem,a.elem);
    return *this;
}
---------------
template<typename T>
void swap(T& a, T& b) // "doskonaa zamiana" (prawie)
{
    T tmp = std::move(a);
    a = std::move(b);
    b = std::move(tmp);
}
---------------
Matrix operator+(const Matrix& a, const Matrix& b)
    // res[i][j] = a[i][j]+b[i][j] dla kadego i oraz j
{
    if (a.dim[0]!=b.dim[0] || a.dim[1]!=b.dim[1])
        throw std::runtime_error("Rne rozmiary macierzy w +");

    Matrix res{a.dim[0],a.dim[1]};
    constexpr auto n = a.size();
    for (int i = 0; i!=n; ++i)
        res.elem[i] = a.elem[i]+b.elem[i];
    return res;
}
---------------
Matrix& operator+(const Matrix& a, const Matrix& b) // uwaga!
{
    Matrix& res = *new Matrix; // alokacja w pamici wolnej
    // res[i][j] = a[i][j]+b[i][j] dla kadego i oraz j
    return res;
}
---------------
class gslice {
    valarray<size_t> siz e;
    valarray<size_t> stride;
    valarray<size_t> d1;
public:
    gslice() = default;
    ~gslice() = default;
    gslice(const gslice&) = default;
    gslice(gslice&&) = default;
    gslice& operator=(const gslice&) = default;
    gslice& operator=(gslice&&) = default;
    // ...
};
---------------
class gslice {
    valarray<size_t> size;
    valarray<size_t> stride;
    valarray<size_t> d1;
public:
    //...
};
---------------
class gslice {
    valarray<size_t> size;
    valarray<size_t> stride;
    valarray<size_t> d1;
public:
    //...
    gslice(const gslice& a);
};
    gslice::gslice(const gslice& a)
    : size{a.size},
    stride{a.stride},
    d1{a.d1}
{
}
---------------
struct S {
    string a;
    int b;
};

S f(S arg)
{
    S s0 {};   // domylna konstrukcja: {"",0}
    S s1 {s0}; // konstrukcja kopiujca
    s1 = arg;  // przypisanie kopiujce
    return s1; // konstrukcja przenoszca
}
---------------
struct X {
    X(int); // wymaga int do inicjacji X
};
---------------
X a {1}; // OK
X b {};  // bd: brak konstruktora domylnego
---------------
struct Y {
    string s;
    int n;
    Y(const string& s); // inicjuje Y acuchem
    Y() = default;      // zezwolenie na domyln inicjacj w domylny sposb
};
---------------
struct Z { // niezmiennik:
           // my_favorite jest indeksem mojego ulubionego elementu wektora elem
           // largest wskazuje najwikszy element wektora elem
    vector<int> elem;
    int my_favorite;
    int* largest;
};
---------------
Z v0;                          // brak inicjacji (ups! moliwo wystpienia niezainicjowanych wartoci)
Z val {{1,2,3},1,&v0.elem[2]}; // OK, ale brzydkie i podatne na bdy
Z v2 = val;                    // kopiuje v2.largest punktw do val
Z v3 = move(val);              // przenosi: val.elem staje si pusty; v3.my_favorite jest poza zakresem
---------------
template<typename T> class Handle {
    T* p;
public:
    Handle(T* pp) :p{pp} { }
    T& operator*() { return *p; }
    ~Handle() { delete p; }
};
---------------
void f1()
{
    Handle<int> h {new int{99}};
    //...
}
---------------
void f2()
{
    Handle<int> h; // bd: nie ma domylnego konstruktora
    //...
}
---------------
void f3()
{
    Handle<int> h1 {new int{7}};
    Handle<int> h2 {h1}; // bd: nie ma konstruktora kopiujcego
    //...
}
---------------
template<typename T>
class Handle {
    //...
    Handle(const Handle& a) :p{new T{*a.p}} { } // klonuje
};
---------------
class Tic_tac_toe {
public:
    Tic_tac_toe(): pos(9) {} // zawsze 9 pozycji

    Tic_tac_toe& operator=(const Tic_tac_toe& arg)
    {
        for(int i = 0; i<9; ++i)
            pos.at(i) = arg.pos.at(i);
        return *this;
    }

    //... inne operacje...

    enum State { empty, nought, cross };
private:
    vector<State> pos;
};
---------------
class Tic_tac_toe {
public:
    Tic_tac_toe(): pos(9) {} // zawsze 9 pozycji
    Tic_tac_toe(const Tic_tac_toe&) = default;
    Tic_tac_toe& operator=(const Tic_tac_toe& arg) = default;
    ~Tic_tac_toe() = default;

    //... inne operacje...

    enum State { empty, nought, cross };
private:
    vector<State> pos;
};
---------------
class Tic_tac_toe {
public:
    //... inne operacje...
    enum State { empty, nought, cross };
private:
    vector<State> pos {Vector<State>(9)};  // zawsze 9 pozycji
};
---------------
class Base {
    //...
    Base& operator=(const Base&) = delete; // uniemoliwia kopiowanie
    Base(const Base&) = delete;

    Base& operator=(Base&&) = delete;      // uniemoliwia przenoszenie
    Base(Base&&) = delete;
};

Base x1;
Base x2 {x1}; // bd: brak konstruktora kopiujcego
---------------
template<typename T>
T* clone(T* p) // zwraca kopi *p
{
    return new T{*p};
};

Foo* clone(Foo*) = delete;   // nie prbuj klonowa Foo
void f(Shape* ps, Foo* pf)
{
    Shape* ps2 = clone(ps);  // w porzdku
    Foo* pf2 = clone(pf);    // bd: funkcja clone(Foo*) jest usunita
}
---------------
struct Z {
    //...
    Z(double);       // mona inicjowa przy uyciu double
    Z(int) = delete; // ale nie przy uyciu int
};

void f()
{
    Z z1 {1};   // bd: Z(int) usunito
    Z z2 {1.0}; // OK
}
---------------
class Not_on_stack {
    //...
    ~Not_on_stack() = delete;
};
---------------
class Not_on_free_store {
    //...
    void* operator new(size_t) = delete;
};
---------------
void f()
{
    Not_on_stack v1;      // bd: nie mona usun
    Not_on_free_store v2; // OK

    Not_on_stack* p1 = new Not_on_stack;            // OK
    Not_on_free_store* p2 = new Not_on_free_store;  // bd: nie mona alokowa
}