# Pointers

Pointers 代表一個物件在 Memory 的位置。其他的程式可以透過 Pointer 讀取該位置資料。

## traditional pointers

```cpp
int a = 1;

// Declaration
int* ptr = &a;

// print out the actual object inside the pointer
std::cout << *ptr << std::endl; // 1

// print out the address of the pointer
std::cout << ptr << std::endl;  // 0x7ffd5268db54
```

### 透過 Pointer 改變原本的物件

```cpp
#include <iostream>
using namespace std;

int main() {
    int a = 1;
    int* ptr = &a;

    std::cout << a << std::endl; // a is originally 1

    // add the referenced object by 1
    *ptr += 1;

    // a is modified by ptr and becomes 2
    std::cout << *ptr << std::endl;
    std::cout << a << std::endl; 
    return 0;
}
```

### 套用 Pointer 於 Functions 上

```cpp
#include <iostream>
using namespace std;

// swap values of two integers
void swap(int &a, int &b) {
    int tmp = a;
    a = b;
    b = tmp;
}

int main() {
    int a = 1;
    int b = 2;

    std::cout << a << std::endl; // 1
    std::cout << b << std::endl; // 2

    swap(a, b);

    // values of a and b are swapped
    std::cout << a << std::endl;
    std::cout << b << std::endl;
    return 0;
}
```

## smart pointers

pointers 既是 c++ 的精髓，也是 c++ 的危險。不當的使用和一些的過失往往會導致 pointers 沒被清乾淨，被程式錯誤使用，最後導致程式崩潰。透過 smart pointers 可以幫助清理不被需要的 pointer 並加以管理正在使用的 pointer，使程式更安全。

### unique pointer

這種 pointer 裡的物件只存在於它被定義的 scope，一旦離開就會自我刪除。這可以阻止 pointer 的共用，降低錯誤的風險。

```cpp
// Example from https://en.cppreference.com/w/cpp/memory/unique_ptr

#include <cassert>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <memory>
#include <stdexcept>
 
struct D
{
    D() { std::cout << "D::D\n"; }
    ~D() { std::cout << "D::~D\n"; }
 
    void bar() { std::cout << "D::bar\n"; }
};
 
// a function consuming a unique_ptr can take it by value or by rvalue reference
std::unique_ptr<D> pass_through(std::unique_ptr<D> p)
{
    p->bar();
    return p;
}
 

int main()
{
       // Create a (uniquely owned) resource
       std::unique_ptr<D> p = std::make_unique<D>();
       
       // Transfer ownership to `pass_through`,
       // which in turn transfers ownership back through the return value
       std::unique_ptr<D> q = pass_through(std::move(p));
       
       // p is now in a moved-from 'empty' state, equal to nullptr
       assert(!p);
}
```

### shared pointer

這種 pointer 裡的物件在沒有 shared\_ptr reference 的情況會自我刪除。這可以保護系統，使其回收不必要的 pointer，以降低錯誤的風險。

```cpp
// Example from https://en.cppreference.com/w/cpp/memory/shared_ptr

#include <chrono>
#include <iostream>
#include <memory>
#include <mutex>
#include <thread>
 
using namespace std::chrono_literals;
 
struct Base
{
    Base() { std::cout << "Base::Base()\n"; }
 
    // Note: non-virtual destructor is OK here
    ~Base() { std::cout << "Base::~Base()\n"; }
};
 
struct Derived: public Base
{
    Derived() { std::cout << "Derived::Derived()\n"; }
 
    ~Derived() { std::cout << "Derived::~Derived()\n"; }
};
 
void print(auto rem, std::shared_ptr<Base> const& sp)
{
    std::cout << rem << "\n\tget() = " << sp.get()
              << ", use_count() = " << sp.use_count() << '\n';
}
 
void thr(std::shared_ptr<Base> p)
{
    std::this_thread::sleep_for(987ms);
    std::shared_ptr<Base> lp = p; // thread-safe, even though the
                                  // shared use_count is incremented
    {
        static std::mutex io_mutex;
        std::lock_guard<std::mutex> lk(io_mutex);
        print("Local pointer in a thread:", lp);
    }
}
 
int main()
{
    std::shared_ptr<Base> p = std::make_shared<Derived>();
 
    print("Created a shared Derived (as a pointer to Base)", p);
 
    std::thread t1{thr, p}, t2{thr, p}, t3{thr, p};
    p.reset(); // release ownership from main
 
    print("Shared ownership between 3 threads and released ownership from main:", p);
 
    t1.join(); t2.join(); t3.join();
 
    std::cout << "All threads completed, the last one deleted Derived.\n";
}
```

### weak pointer

weak pointer 是一種 pointer，必須轉換成 shared\_ptr 才能讀取資料。可以用於確保取得 reference 物件時物件存在。

<pre class="language-cpp"><code class="lang-cpp"><strong>// Example from https://en.cppreference.com/w/cpp/memory/weak_ptr
</strong><strong>
</strong><strong>#include &#x3C;iostream>
</strong>#include &#x3C;memory>
 
std::weak_ptr&#x3C;int> gw;
 
void observe()
{
    std::cout &#x3C;&#x3C; "gw.use_count() == " &#x3C;&#x3C; gw.use_count() &#x3C;&#x3C; "; ";
    // we have to make a copy of shared pointer before usage:
    if (std::shared_ptr&#x3C;int> spt = gw.lock()) {
        std::cout &#x3C;&#x3C; "*spt == " &#x3C;&#x3C; *spt &#x3C;&#x3C; '\n';
    }
    else {
        std::cout &#x3C;&#x3C; "gw is expired\n";
    }
}
 
int main()
{
    {
        auto sp = std::make_shared&#x3C;int>(42);
        gw = sp;
 
        observe();
    }
 
    observe();
}
</code></pre>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://acezxn.gitbook.io/vex-ji-qi-ren-cheng-shi-jiao-xue/jin-jie-jiao-xue/jin-jie-c++/pointers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
