README: note managed pointer size differences between rcp and shared_ptr

This commit is contained in:
Josh Holtrop 2026-02-25 09:30:59 -05:00
parent 771473b62a
commit 339f1ce9d6

View File

@ -319,6 +319,7 @@ for (auto & l : g_listeners) l->events_received++;
| | `rcp` | `std::shared_ptr` |
|---|---|---|
| Pointer size | One pointer | Two pointers (object + control block) |
| Reference count location | Inside the object | Separate control block (extra allocation) |
| Class requirement | `rcp_managed_root` / `rcp_managed` macro | None (any type) |
| Weak pointers | No | Yes (`std::weak_ptr`) |
@ -326,7 +327,14 @@ for (auto & l : g_listeners) l->events_received++;
| Pointer to `this` | implicit conversion from `this` or explicit `get_rcp()` | `std::enable_shared_from_this` |
| Checked downcast | `rcp_dynamic_cast` | `std::dynamic_pointer_cast` |
The intrusive design means each managed object requires only one heap
Because `rcp` stores only a single raw pointer, `sizeof(rcp<T>)` equals
`sizeof(T *)` — typically 8 bytes on a 64-bit platform.
`std::shared_ptr` stores both a pointer to the object and a pointer to the
control block, so `sizeof(std::shared_ptr<T>)` is typically 16 bytes.
This makes `rcp` more efficient to pass by value, copy, and store in
containers.
The intrusive design also means each managed object requires only one heap
allocation instead of two which can improve performance for many applications.
The trade-off is that the class must be written with `rcp` in mind.