Here\'s a notable video (Stop teaching C) about that paradigm change to take in teaching the c++ language.
And an also notable blog post
Some APIs might expect you to create objects with new
but will take over ownership of the object. The Qt library for example has a parent-child model where the parent deletes its children. If you use a smart pointer, you are going to run into double-deletion issues if you're not careful.
Example:
{
// parentWidget has no parent.
QWidget parentWidget(nullptr);
// childWidget is created with parentWidget as parent.
auto childWidget = new QWidget(&parentWidget);
}
// At this point, parentWidget is destroyed and it deletes childWidget
// automatically.
In this particular example, you can still use a smart pointer and it will be fine:
{
QWidget parentWidget(nullptr);
auto childWidget = std::make_unique(&parentWidget);
}
because objects are destroyed in reverse order of declaration. unique_ptr
will delete childWidget
first, which will make childWidget
unregister itself from parentWidget
and thus avoid double-deletion. However, most of the time you don't have that neatness. There are many situations where the parent will be destroyed first, and in those cases, the children will get deleted twice.
In the above case, we own the parent in that scope, and thus have full control of the situation. In other cases, the parent might not be hours, but we're handing ownership of our child widget to that parent, which lives somewhere else.
You might be thinking that to solve this, you just have to avoid the parent-child model and create all your widgets on the stack and without a parent:
QWidget childWidget(nullptr);
or with a smart pointer and without a parent:
auto childWidget = std::make_unique(nullptr);
However, this will blow up in your face too, since once you start using the widget, it might get re-parented behind your back. Once another object becomes the parent, you get double-deletion when using unique_ptr
, and stack deletion when creating it on the stack.
The easiest way to work with this is to use new
. Anything else is either inviting trouble, or more work, or both.
Such APIs can be found in modern, non-deprecated software (like Qt), and have been developed years ago, long before smart pointers were a thing. They cannot be changed easily since that would break people's existing code.