Memory and ownership
There is no garbage collector. Native lifetime is part of the program’s correctness model.
The native model
| C# intuition | Sharp Runtime / C++ reality |
|---|---|
| Managed reference | Usually an explicitly chosen smart pointer or a reference with a proven lifetime |
| Value type | Ordinary stack/member value with C++ copy and move behavior |
| GC lifetime | Scope, owner destruction and RAII |
| Shared graph | std::shared_ptr only when ownership is genuinely shared; cycles must be avoided or broken |
| Borrowed parameter | Reference or pointer whose lifetime is not extended |
Porting rules
- Start with one clear owner; add shared ownership only when the domain requires it.
- Prefer stack values and direct members for value-like types.
- Treat callback captures as lifetime decisions; avoid capturing raw
thispast owner teardown. - Do not assume collection insertion or event subscription copies a managed object graph.
- Read class-specific documentation for copy/move reductions and non-owning links.
RAII and resources
Streams, locks, sockets and other native resources should be scoped so destructors provide cleanup. Explicit Dispose-shaped APIs may exist for source compatibility, but C++ destruction remains the safety net.
Differences from .NET
- No tracing collector means reference cycles can leak.
- Destruction timing is normally deterministic rather than collection-dependent.
- Copy and move can duplicate or transfer state; check each type’s semantics.
- A reference can dangle if the owner ends; the runtime cannot repair ordinary C++ lifetime errors.
Design ownership before transliteration
A mechanical replacement of every C# reference with shared_ptr obscures ownership and can create cycles. Port the lifetime model, not just the syntax.