---
# System prepended metadata

title: CPP
tags: [Programming Language, CPP, III]

---

CPP
===

###### tags: `III` `Programming Language` `CPP`

## Basic
```
int n = 10;      // 定義變數
int *p = &n;     // 定義指標，儲存 n 的位址
int &r = n;      // 定義參考，是 n 的別名
```
## Smart Pointer
* ~~auto_ptr~~ (depreacated)
* unique_ptr
  * Only one unique_ptr can point to one resource.
```=cpp
unique_ptr<Foo> ptr1(new Foo);
cout << ptr1.get() << endl; // 0x...
// Error: can't copy unique_ptr
//unique_ptr<A> ptr2 = ptr1;
unique_ptr<Foo> ptr2 = move(ptr1);
cout << ptr1.get() << endl; // 0
cout << ptr2.get() << endl; // 0x...
```
* shared_ptr
  * Many shared_ptr can point to a single resource.
  * shared_ptr maintains reference count.
  * The resource will not be destroyed until reference count becomes zero.
```=cpp
shared_ptr<Foo> ptr3 = make_shared<Foo>();
shared_ptr<Foo> ptr4(ptr3);
cout << ptr3.get() << endl;       // 0x...
cout << ptr4.get() << endl;       // 0x...
cout << ptr3.use_count() << endl; // 2
cout << ptr4.use_count() << endl; // 2
ptr3.reset();
cout << ptr3.use_count() << endl; // 0
cout << ptr4.use_count() << endl; // 1
ptr4.reset();
cout << ptr4.use_count() << endl; // 0
```
:::warning
Cyclic Dependency
```=cpp
class Foo
{
public:
    shared_ptr<Foo> parent;

public:
    shared_ptr<Foo> child;
};

shared_ptr<Foo> cyc_dep()
{
    shared_ptr<Foo> p = make_shared<Foo>();
    shared_ptr<Foo> q = make_shared<Foo>();
    cout << p.use_count() << endl; // 1

    p->child = q;
    q->parent = p;
    cout << p.use_count() << endl; // 2

    return p;
}
```
```graphviz
digraph hierarchy {

                nodesep=3.0
                bgcolor="transparent"
                node [color=Black,fontname=Courier]
                edge [style=solid, color=Black]
                
                {rank=same "shared_ptr<Foo> p"  "foo1" }
                {rank=same "shared_ptr<Foo> q"  "foo2" }

                "shared_ptr<Foo> p"->"foo1" 
                "shared_ptr<Foo> q"->"foo2"
                "foo1"->"foo2" [color=Blue]
                "foo2"->"foo1" [color=Blue]
}
```
:::

* weak_ptr
  * A weak_ptr is created as a copy of shared_ptr. 
  * It provides access to an object that is owned by one or more shared_ptr instances but does not participate in reference counting.
  * The existence or destruction of weak_ptr has no effect on the shared_ptr or its other copies.
```=cpp
class Bar
{
public:
    shared_ptr<Bar> parent;

public:
    weak_ptr<Bar> child;
};

shared_ptr<Bar> weak_cyc_dep()
{
    std::shared_ptr<Bar> p = std::make_shared<Bar>();
    std::shared_ptr<Bar> q = std::make_shared<Bar>();
    cout << p.use_count() << endl; // 1

    p->child = q;
    q->parent = p;
    cout << p.use_count() << endl; // 2

    return p;
}
```
```graphviz
digraph hierarchy {

                nodesep=3.0
                bgcolor="transparent"
                node [color=Black,fontname=Courier]
                edge [style=solid, color=Black]
                
                {rank=same "shared_ptr<Foo> p"  "foo1" }
                {rank=same "shared_ptr<Foo> q"  "foo2" }

                "shared_ptr<Foo> p"->"foo1" 
                "shared_ptr<Foo> q"->"foo2"
                "foo1"->"foo2" [color=Blue, style=dashed] 
                "foo2"->"foo1" [color=Blue]
}
``` 
Example
```=cpp
#include <iostream>
#include <memory>
using namespace std;

class Foo
{
public:
    shared_ptr<Foo> parent;

public:
    shared_ptr<Foo> child;
};

class Bar
{
public:
    shared_ptr<Bar> parent;

public:
    weak_ptr<Bar> child;
};

shared_ptr<string> shared_pointer();
shared_ptr<Foo> cyc_dep();
shared_ptr<Bar> weak_cyc_dep();

int main()
{

    cout << "===unique_ptr===" << endl;
    unique_ptr<Foo> ptr1(new Foo);
    cout << ptr1.get() << endl; // 0x...
    // Error: can't copy unique_ptr
    //unique_ptr<A> ptr2 = ptr1;
    unique_ptr<Foo> ptr2 = move(ptr1);
    cout << ptr1.get() << endl; // 0
    cout << ptr2.get() << endl; // 0x...

    cout << "===shared_ptr===" << endl;
    shared_ptr<Foo> ptr3 = make_shared<Foo>();
    shared_ptr<Foo> ptr4(ptr3);
    cout << ptr3.get() << endl;       // 0x...
    cout << ptr4.get() << endl;       // 0x...
    cout << ptr3.use_count() << endl; // 2
    cout << ptr4.use_count() << endl; // 2
    ptr3.reset();
    cout << ptr3.use_count() << endl; // 0
    cout << ptr4.use_count() << endl; // 1
    ptr4.reset();
    cout << ptr4.use_count() << endl; // 0

    cout << "===shared pointer===" << endl;
    std::shared_ptr<string> r1 = shared_pointer();
    cout << r1.use_count() << endl; // 1
    cout << r1.get() << endl;
    cout << *r1 << endl; // abc

    cout << "===cyclic dependency===" << endl;
    std::shared_ptr<Foo> r2 = cyc_dep();
    cout << r2.use_count() << endl; // 2

    cout << "===weak cyclic dependency===" << endl;
    std::shared_ptr<Bar> r3 = weak_cyc_dep();
    cout << r3.use_count() << endl; // 1

    return 0;
}

shared_ptr<string> shared_pointer()
{
    shared_ptr<string> p = make_shared<string>();
    cout << p.get() << endl;
    *p = "abc";
    return p;
}

shared_ptr<Foo> cyc_dep()
{
    shared_ptr<Foo> p = make_shared<Foo>();
    shared_ptr<Foo> q = make_shared<Foo>();
    cout << p.use_count() << endl; // 1

    p->child = q;
    q->parent = p;
    cout << p.use_count() << endl; // 2

    return p;
}

shared_ptr<Bar> weak_cyc_dep()
{
    std::shared_ptr<Bar> p = std::make_shared<Bar>();
    std::shared_ptr<Bar> q = std::make_shared<Bar>();
    cout << p.use_count() << endl; // 1

    p->child = q;
    q->parent = p;
    cout << p.use_count() << endl; // 2

    return p;
}
```