Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a safe way to use C++11 Smart Pointer and the Interface for Raw Pointer together?

I want to use C++11 Smart Pointers in new projects, and encounter a problem. Many current projects still use raw pointers as parameters in their interface and have no interface for smart pointers, e.g. QMainWindow::setCentralWidget.

To keep type consistent, I have to pass the stored pointer from get() like this segment:

QMainWindow win;

std::shared_ptr<QWidget> scrollArea{ std::make_shared<QScrollArea>() };
// QScrollArea is a derived class of QWidget.

win.setCentralWidget(scrollArea.get());

But I can't make sure whether other methods in Qt execute operator delete on the stored pointer of scrollArea.

Will it cause memory leak or other problems if some methods in Qt do that?

I've checked the latest C++ Standard CD and found nothing on that. Seems it's an undefined behavior.

If doing this is an undefined behavior and dangerous, is there a safe way to use smart pointer(s) with the interface for raw pointer(s)?

like image 565
UniversE Avatar asked May 21 '13 07:05

UniversE


People also ask

In what kind of circumstances would you use a raw pointer instead of a smart pointer?

The rule would be this - if you know that an entity must take a certain kind of ownership of the object, always use smart pointers - the one that gives you the kind of ownership you need. If there is no notion of ownership, never use smart pointers.

Which smart pointer should be used when you want shared ownership but not reference counting?

If you find that you need to share data or utilize reference counting, you should use a std::shared_ptr . If you need to reference shared data but don't want to contribute to the reference count, use a std::weak_ptr .

What is smart pointer when should we use it asked me to implement unique_ptr of my own?

std::unique_ptr s are useful when you want to tie the lifetime of the object to a particular block of code, or if you embedded it as member data inside another object, the lifetime of that other object. The object exists until the containing block of code is exited, or until the containing object is itself destroyed.

Why Auto_ptr is deprecated?

Why is auto_ptr deprecated? It takes ownership of the pointer in a way that no two pointers should contain the same object. Assignment transfers ownership and resets the rvalue auto pointer to a null pointer. Thus, they can't be used within STL containers due to the aforementioned inability to be copied.

What is smart pointer in C++11?

C++11 comes up with its own mechanism that’s Smart Pointer. When the object is destroyed it frees the memory as well. So, we don’t need to delete it as Smart Pointer does will handle it. A Smart Pointer is a wrapper class over a pointer with an operator like * and -> overloaded.

Do we need to delete a smart pointer in C++?

So, we don’t need to delete it as Smart Pointer does will handle it. A Smart Pointer is a wrapper class over a pointer with an operator like * and -> overloaded. The objects of the smart pointer class look like normal pointers. But, unlike Normal Pointers it can deallocate and free destroyed object memory.

What is a raw pointer in C++?

In modern C++, raw pointers are only used in small code blocks of limited scope, loops, or helper functions where performance is critical and there is no chance of confusion about ownership. The following example compares a raw pointer declaration to a smart pointer declaration. void UseRawPointer() { // Using a raw pointer -- not recommended.

When to use smart pointers and when not to?

The rule would be this - if you know that an entity must take a certain kind of ownership of the object, always use smart pointers - the one that gives you the kind of ownership you need. If there is no notion of ownership, never use smart pointers. Show activity on this post.


2 Answers

There's no such way in the general case. For each "legacy" interface you want to use, you must read its documentation to see how it interacts with ownership (which is what std smart pointers encapsulate). A single object can only be managed by one ownership scheme.

With Qt in particular, it's definitely not safe to mix smart pointers and Qt management. Qt's parent/child relationship between QObjects includes ownership semantics (children are deleted when their parent is), so you cannot safely mix this with any other ownership scheme (such as std smart pointers).

Note that the Qt docs you link to explicitly state that "QMainWindow takes ownership of the widget pointer and deletes it at the appropriate time."

like image 55
Angew is no longer proud of SO Avatar answered Nov 02 '22 17:11

Angew is no longer proud of SO


Unfortunately, if you are using an interface that uses raw pointers, you will need to consult the documentation to determine if the method does or does not take ownership of the provided pointer.

If the function takes ownership, then you must invoke .release() to transfer the ownership to the function. If the function does not take ownership, then you would pass the object with .get().

like image 42
Michael Aaron Safyan Avatar answered Nov 02 '22 19:11

Michael Aaron Safyan