Smart Pointers¶
Smart Pointers¶
S++ doesn’t use raw pointers in code anywhere. However, there must be a way to store information on the heap, especially for hierarchical casting. There are a few different smart pointers that allow for the use of the heap:
Single[T]
: A simple heap-allocated pointer. This is the most basic smart pointer, and analogous to C++’sstd::unique_ptr<T>
or Rust’sBox<T>
type. This is used for single ownership.Shared[T]
: A reference-counted pointer. This is used for shared ownership, and is analogous to C++’sstd::shared_ptr<T>
type. It maintains counters for the number of strong and weak references to the data. Like Rust’sRc<T>
type, the internal data is immutable, to follow the strict memory safety rules of S++.Shadow[T]
: A weak reference to a reference-counted pointer. This is used to break cycles in reference-counted pointers, and is analogous to C++’sstd::weak_ptr<T>
and Rust’sWeak<T>
type.Thared[T]
: A thread-safe reference-counted pointer. This is used for shared ownership across threads, and is analogous to C++’sstd::shared_ptr<T>
type with anstd::atomic<int>
counter, and Rust’sArc<T>
type.
Single[T]
¶
The Single[T]
type is similar to Rust’s Box<T>
and C++’s std::unique_ptr<T>
. It is used for single ownership of
heap-allocated data. The Single[T]
type is a smart pointer that owns the data it points to, and will deallocate the
data when it goes out of scope. There are cast function overloads for the Single[T]
type, because the value it points
to in memory may have additional information for the subtype.
let x = Single(data=5)
Member access into a Single[T]
is identical to accessing members of the T
type; there is no need to dereference the
pointer. Whilst data=
is required to set the value, .data
is not accessible nor does it exist at all; it just
provides a uniform way to set the initial value.
Shadow[T]
¶
The Shadow[T]
type is similar to Rust’s Weak<T>
and C++’s std::weak_ptr<T>
. It is used to break cycles in
reference-counted pointers. The Shadow[T]
type is created from a Shared[T]
type, and will increment the weak
reference count of the Shared[T]
type. The Shadow[T]
type can be upgraded to a Shared[T]
type, which will
increment the strong reference count of the Shared[T]
type.
let x = Shared(data=5)
let y = x.shadow()
Member access into a Shadow[T]
, like for Shared[T]
, is identical to accessing members of the T
type - there is no
need to dereference the pointer.
Thared[T]
¶
The Thared[T]
type (Thread-safe Shared) is similar to Rust’s Arc<T>
and C++’s std::shared_ptr<T>
type with
an std::atomic<int>
counter. It is used for shared ownership of heap-allocated data across threads. The Thared[T]
type maintains the same two counters as Shared[T]
, but with Atomic[U32]
types.