Pointers
Pointers 代表一個物件在 Memory 的位置。其他的程式可以透過 Pointer 讀取該位置資料。
traditional pointers
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 改變原本的物件
#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 上
#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 的共用,降低錯誤的風險。
// 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,以降低錯誤的風險。
// 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 物件時物件存在。
// Example from https://en.cppreference.com/w/cpp/memory/weak_ptr
#include <iostream>
#include <memory>
std::weak_ptr<int> gw;
void observe()
{
std::cout << "gw.use_count() == " << gw.use_count() << "; ";
// we have to make a copy of shared pointer before usage:
if (std::shared_ptr<int> spt = gw.lock()) {
std::cout << "*spt == " << *spt << '\n';
}
else {
std::cout << "gw is expired\n";
}
}
int main()
{
{
auto sp = std::make_shared<int>(42);
gw = sp;
observe();
}
observe();
}
Last updated