Skip to main content

Ownership and safety

The library uses C++23 value types for themes, strong enums for variants and std::expected for recoverable value errors. Widget ownership follows Qt's parent tree. QApplication owns the installed style, widgets own their animations, and signal connections use a receiver context.

make_child constructs a widget owned by its parent and returns a borrowed reference. The helper constrains the template to a constructible QWidget subclass. It removes a repeated allocation and parenting step; it does not add a borrow checker.

auto& button = shadcn::make_child<shadcn::Button>(window, "Continue");
QPointer<shadcn::Button> observed(&button);
QObject::connect(&timer, &QTimer::timeout, &window, [observed] {
if (observed) observed->setEnabled(true);
});

Include QTimer and QPointer in the application using this snippet. The receiver context prevents the callback from running after the window is destroyed. QPointer becomes null when its QObject is destroyed. Neither makes concurrent widget access safe. Keep all widget operations on the GUI thread.

Use stack objects for root widgets. Use Qt parenting for children. Use std::unique_ptr for an independent root or a resource that does not inherit QObject when it is the sole owner. Never give a widget owned by its parent a second owning smart pointer. Do not reparent an object whose stack lifetime conflicts with the new parent's lifetime.

Validation rejects invalid finite ranges, NaN and infinity at the core's public interfaces. An invalid theme update leaves the old value intact. Qt widgets retain Qt's inherited contracts, including QProgressBar's treatment of integer values outside the range.

C++ does not provide Rust's compile time lifetime and aliasing checks. These ownership rules reduce common mistakes, but misuse remains possible. AddressSanitizer and UndefinedBehaviorSanitizer are configured for supported toolchains. Passing tests do not prove that the library, Qt or an application is free of memory errors.

Qt's object ownership documentation explains the parent tree and rules for stack lifetimes. QObject documentation defines connection and thread affinity behaviour.