How to copy QWidget through pointers in C++ - c++

My goal is this:
QWidget *p = new QSpinBox(0); // This can be any type of QWidget.
QWidget* Get()
{
/*
Here using p, I need to return a NEW object of QSpinBox or whatever
the qwidget assigned to p. I can't return p because it will be deleted
after this method, so the next time p would be empty.
*/
}
It's used for the QStyledItemDelegates::createEditor() method. The widget returned from get will be deleted when the delegate editing is done.

All QObjects are not copyable by definition. See its header file.
Same applies to QSpinBox.
Reason is simple cloning of signal slots memory management could lead to unpredictable results, so it was disabled by design.

The copy of a pointer to an object doesn't copy the object in any way. In Qt the copy of QObject derived classes is indeed disabled, but you can copy pointers to the object around as much as you want, or until you run out of memory...
Due to the design of Qt QObject derived classes have unique identities. This means they must not be copied, at least in the rational sense of the term. You could however write your own "clone function" that creates a new instance with unique identity and applies all of the properties of the object p points to to the new instance. E.g. you can fake it to a certain amount but don't expect to get a copy functionally identical to the original. If you want to get a fully functionally identical clone, you will have to implement your own signal and slot mechanism instead of using the one provided by Qt.
You CAN indeed return p - but it will point to nothing if you call delete on it. Keep in mind returning p will simply copy the pointer, it has nothing to do with the actual object pointed to. p is just a number.
Edit:
At a deeper look at the "reflection facilities" provided by Qt, it looks like you could get signals and slots to clone, but it is not pretty - you have to query every QMetaMethod of the QMetaObject associated with the particular instance to find the signals, but then you hit a brick wall - you will have to resort to using private APIs (a big no-no in 99.9999% of the cases) in order to query for the signal receivers in order to connect the new copy to them as well. Definitely not something that was intended to be done. In short, you need to rethink your strategy at getting the problem solved.
Overall, as I mentioned in the comments, your problem seems to be bad design, and even though it is technically possible to make the bad design work, you'd be much better if you simply improve your design and avoid arduous if not even masochistic endeavors.

s is a pointer, which can be copied and modified at will; modifications to the copy will never affect the original. If what you meant was in fact the object which s referred to, then it's sufficient to provide it with a copy constructor and a copy assignment operator; depending on the content of the class, the compiler may have generated these for you.
Depending on the content, it's also possible that the compiler generated versions don't do what you need.
Given the name of the class, I suspect that it is part of Qt. In that case, check the documentation. It may support cloning, in which case, what you probably want is a clone.

Related

Program design concerning polymorphism & resource management

I have a class called Widget. This class is abstract and has virtual methods. To avoid object slicing all Widgets are stored as references or pointers. I have several classes with constructors that store internally the widget given to them; thus the Widget stored must have been initialized outside the constructor and cannot be destroyed before the object is, therefore usually the Widget is allocated via dynamic memory. My question is regarding how to handle this dynamic memory; I have compiled a list of options (feel free to suggest others.) Which is the most idiomatic?
1. Smart pointers. Smart pointers seem like the right choice, but since I'm using C++98 I have to write my own. I also think that writing smart_pointer<Widget> all the time is a little ugly.
2. Copy Widgets when stored. Another course of action is to store a copy of the passed-in Widget instead of the original. This might cause object-slicing, but I'm not sure. Also, users might want to write classes themselves that store passed-in Widgets, and I wouldn't want to make it too complicated.
3. Let the user handle everything. I could perhaps make the user make sure that the Widget is deleted on time. This seems to be what Qt does (?). However, this again complicates things for the user.
I personally like this approach (it is not always applicable, but I used it successfully multiple times):
class WidgetOwner
{
vector<Widget*> m_data;
public:
RegisterWidget(Widget *p) { m_data.push_back(p); }
~WidgetOwner() { for (auto &p : m_data) delete p; }
};
This simple class just stores pointers. This class can store any derivatives of Widget provided that Widget has virtual destructor. For a polymorphic class this should not be a problem.
Note that once Widget is registered, it cannot be destroyed unless everything is destroyed.
The advantage of this approach is that you can pass around pointers freely. They all will be valid until the storage will be destroyed. This is sort of hand made pool.
Which is the most idiomatic?
The most idiomatic would certainly be what next versions of c++ decided to be "the way to go", and that would be smart pointers (You can find/use an implementation on boost for example, also other ones on the internet might be simpler for inspiration).
You can also decide that since you are using c++98 (that's a huge factor to take into consideration), you take what's idiomatic for that context, and since that was pretty much no man's land, the answer is most likely whatever home made design is the most appealing to you.
I think smart pointer is best choice. And if you feel template is ugly, try the typedef

Is there a way to optimize shared_ptr for the case of permanent objects?

I've got some code that is using shared_ptr quite widely as the standard way to refer to a particular type of object (let's call it T) in my app. I've tried to be careful to use make_shared and std::move and const T& where I can for efficiency. Nevertheless, my code spends a great deal of time passing shared_ptrs around (the object I'm wrapping in shared_ptr is the central object of the whole caboodle). The kicker is that pretty often the shared_ptrs are pointing to an object that is used as a marker for "no value"; this object is a global instance of a particular T subclass, and it lives forever since its refcount never goes to zero.
Using a "no value" object is nice because it responds in nice ways to various methods that get sent to these objects, behaving in the way that I want "no value" to behave. However, performance metrics indicate that a huge amount of the time in my code is spent incrementing and decrementing the refcount of that global singleton object, making new shared_ptrs that refer to it and then destroying them. To wit: for a simple test case, the execution time went from 9.33 seconds to 7.35 seconds if I stuck nullptr inside the shared_ptrs to indicate "no value", instead of making them point to the global singleton T "no value" object. That's a hugely important difference; run on much larger problems, this code will soon be used to do multi-day runs on computing clusters. So I really need that speedup. But I'd really like to have my "no value" object, too, so that I don't have to put checks for nullptr all over my code, special-casing that possibility.
So. Is there a way to have my cake and eat it too? In particular, I'm imagining that I might somehow subclass shared_ptr to make a "shared_immortal_ptr" class that I could use with the "no value" object. The subclass would act just like a normal shared_ptr, but it would simply never increment or decrement its refcount, and would skip all related bookkeeping. Is such a thing possible?
I'm also considering making an inline function that would do a get() on my shared_ptrs and would substitute a pointer to the singleton immortal object if get() returned nullptr; if I used that everywhere in my code, and never used * or -> directly on my shared_ptrs, I would be insulated, I suppose.
Or is there another good solution for this situation that hasn't occurred to me?
Galik asked the central question that comes to mind regarding your containment strategy. I'll assume you've considered that and have reason to rely on shared_ptr as a communical containment strategy for which no alternative exists.
I have to suggestions which may seem controversial. What you've defined is that you need a type of shared_ptr that never has a nullptr, but std::shared_ptr doesn't do that, and I checked various versions of the STL to confirm that the customer deleter provided is not an entry point to a solution.
So, consider either making your own smart pointer, or adopting one that you change to suit your needs. The basic idea is to establish a kind of shared_ptr which can be instructed to point it's shadow pointer to a global object it doesn't own.
You have the source to std::shared_ptr. The code is uncomfortable to read. It may be difficult to work with. It is one avenue, but of course you'd copy the source, change the namespace and implement the behavior you desire.
However, one of the first things all of us did in the middle 90's when templates were first introduced to the compilers of the epoch was to begin fashioning containers and smart pointers. Smart pointers are remarkably easy to write. They're harder to design (or were), but then you have a design to model (which you've already used).
You can implement the basic interface of shared_ptr to create a drop in replacement. If you used typedefs well, there should be a limited few places you'd have to change, but at least a search and replace would work reasonably well.
These are the two means I'm suggesting, both ending up with the same feature. Either adopt shared_ptr from the library, or make one from scratch. You'd be surprised how quickly you can fashion a replacement.
If you adopt std::shared_ptr, the main theme would be to understand how shared_ptr determines it should decrement. In most implementations shared_ptr must reference a node, which in my version it calls a control block (_Ref). The node owns the object to be deleted when the reference count reaches zero, but naturally shared_ptr skips that if _Ref is null. However, operators like -> and *, or the get function, don't bother checking _Ref, they just return the shadow, or _Ptr in my version.
Now, _Ptr will be set to nullptr (or 0 in my source) when a reset is called. Reset is called when assigning to another object or pointer, so this works even if using assignment to nullptr. The point is, that for this new type of shared_ptr you need, you could simply change the behavior such that whenever that happens (a reset to nullptr), you set _Ptr, the shadow pointer in shared_ptr, to the "no value global" object's address.
All uses of *,get or -> will return the _Ptr of that no value object, and will correctly behave when used in another assignment, or reset is called again, because those functions don't rely upon the shadow pointer to act upon the node, and since in this special condition that node (or control block) will be nullptr, the rest of shared_ptr would behave as though it was pointing to nullptr correctly - that is, not deleting the global object.
Obviously this sounds crazy to alter std::pointer to such application specific behavior, but frankly that's what performance work tends to make us do; otherwise strange things, like abandoning C++ occasionally in order to obtain the more raw speed of C, or assembler.
Modifying std::shared_ptr source, taken as a copy for this special purpose, is not what I would choose (and, factually, I've faced other versions of your situation, so I have made this choice several times over decades).
To that end, I suggest you build a policy based smart pointer. I find it odd I suggested this earlier on another post today (or yesterday, it's 1:40am).
I refer to Alexandrescu's book from 2001 (I think it was Modern C++...and some words I don't recall). In that he presented loki, which included a policy based smart pointer design, which is still published and freely available on his website.
The idea should have been incorporated into shared_ptr, in my opinion.
Policy based design is implemented as the paradigm of a template class deriving from one or more of it's parameters, like this:
template< typename T, typename B >
class TopClass : public B {};
In this way, you can provide B, from which the object is built. Now, B may have the same construction, it may also be a policy level which derives from it's second parameter (or multiple derivations, however the design works).
Layers can be combined to implement unique behaviors in various categories.
For example:
std::shared_ptr and std::weak_ptrare separate classes which interact as a family with others (the nodes or control blocks) to provide smart pointer service. However, in a design I used several times, these two were built by the same top level template class. The difference between a shared_ptr and a weak_ptr in that design was the attachment policy offered in the second parameter to the template. If the type is instantiated with the weak attachment policy as the second parameter, it's a weak pointer. If it's given a strong attachment policy, it's a smart pointer.
Once you create a policy designed template, you can introduce layers not in the original design (expanding it), or to "intercept" behavior and specialize it like the one you currently require - without corrupting the original code or design.
The smart pointer library I developed had high performance requirements, along with a number of other options including custom memory allocation and automatic locking services to make writing to smart pointers thread safe (which std::shared_ptr doesn't provide). The interface and much of the code is shared, yet several different kinds of smart pointers could be fashioned simply by selecting different policies. To change behavior, a new policy could be inserted without altering the existing code. At present, I use both std::shared_ptr (which I used when it was in boost years ago) and the MetaPtr library I developed years ago, the latter when I need high performance or flexible options, like yours.
If std::shared_ptr had been a policy based design, as loki demonstrates, you'd be able to do this with shared_ptr WITHOUT having to copy the source and move it to a new namespace.
In any event, simply creating a shared pointer which points the shadow pointer to the global object on reset to nullptr, leaving the node pointing to null, provides the behavior you described.

Is it possible for d_ptr to be NULL when Object is valid and alive?

I have a class MyAction which derives from the QWidgetAction which derives from the QAction.
When I call QWidget::addActions(QList<QAction*> actions), I have exception on trying to get d_ptr and use it (inside QWidget, not by myself) from action in list:
QActionPrivate *apriv = action->d_func();
apriv->widgets.append(this);
Code above is taken from QWidget source file. By the way, my action is placed in actions list as cast of this pointer which of type MyAction:
actions->push_back(this);
I think that the reason of exception in that that I trying to push into QList my class MyAction, casting const this pointer to QAction*.
If d-pointer pattern is used properly then it never can be null.
D-pointer have to point to valid memory block which will live as long as object lives.
Only exception for this role are classes implementing copy on write which provide null state (for example QString), but this never applies to QObjects.
Your problem must be result of some dangling pointer or other memory issue. Or incorrect type casting. In such cases call stack doesn't have to point to source of problem, problem can be almost anywhere.
I recommend to run your program with valgrind or other memory checking tool. Or some static analysis tool.
You should never use d_func() from client code. The whole point of the pimpl idiom is to stay away from the implementation details and that the library can freely change implementation details like data representation, internal methods and so on.
That is, d_func() along with d_ptr is meant for internal usage. If you need to access it for some reason, that means you seem to violate the design principle of the library, or you are trying to access something that should be exposed to the API, but was not yet needed.
Based on your exact use case - which we do not know, I would suggest to consider these alternatives.
The problem was in that I created MyAction variable on the stack, so, actually, QObject wasn't alive when I'm trying to pass it to QWidget function. That's why I couldn't get d-pointer different from NULL. I couldn't knew that object was actually dead, all strings and variables inside my action was valid.

should we delete the observer when unregister it?

Observer *o = New Observer();
Subject *s = new Subject() ;
s->register(o);
//Is it a good practice to delete the observer in the unregister function?
//I feel it is not. As the Observer object might still be in use, for example ,
//it might be registered to another Subject.
s->unregister(o);
//So it is safe to rely on the client code to delete the object or rely on the smart pointer things
delete o;
I want to confirm whether my above understanding is correct regarding who should delete the observer object.
I agree with your observation. It is not a good practice to delete the observer in the unregister function - for the simple fact that "one who creates the resource must be responsible for deleting the resource"
This will avoid
Magic behavior as perceived by the creator.
Code behavior will be well defined - one who creates must delete. Which will lay overall foundation of understanding of development for new developers to your system.
Similar topic are discussed under lengths in all books with different nomenclature.
I would say use smart pointers as no need to remember to call the delete explictly.
From a design point of view it should be superfluous (while not wrong) to unregister the subjects, if the observer is well implemented. Relying on external code for a behaviour to be robust if it can be enforced can always be considered as poor design.
Regarding the use of smart pointers, if you need the control on the destruction point for some reason (close files at a given point in time for example to avoid access problems in later code) then you should delete explicitly, otherwise it is far more comfortable to rely on smart pointers. That is why there are existing.
As the Subject did not allocate the Observer, it should not attempt to deallocate it. This allows the client of Subject to manage the lifetime and allocation strategy of Observers in any way it chooses (custom allocator, statically allocated, automatic variable). It doesn't force the client to use new.
Obviously it is still to clients responsibility not to allow the Observer to be destroyed before it is "unregistered".
E.g.
Observer o;
Subject s;
s.register(&o); // could take a reference
// ...
s.unregister(&o);
// No potential for forgotten deletes
It depends on your design. I personally prefer that deleting the Observer will automatically disassociate it with the subject, i.e deregister itself in the destructor. That saves the need to bother to deregister, which would require you to have references to both the Subject and the Observer at the point of destruction.
Smartpointer or client code (do not transfer ownership if possible)
If client code has created the object let the same code to destroy it :)
Another argument against deleting is what the Subject object communicates.
By deleting the object your Subject object has taken ownership of the object, as it controls its lifetime. As a raw pointer is passed into the object, and not an auto_ptr or an unique_ptr I would assume as a user of Subject that it does not take ownership of the object without looking at the code. So I would say that the interface of Subject does not communicate that it takes ownership of the object. So Subject should not delete it, because someone else (probably) has ownership of it.
In general, you should avoid side effects like deleting the pointer to an object in a container, unless the container is responsible for creating the pointer as well.
The problems of pointers with the Observer pattern runs a bit deeper than this as well.
An Observer inherently has a reference of some kind to the Subject. If that reference is a direct reference (e.g. not a handle), then if that object goes out of scope or gets deleted, when the Observer makes a Notify(...) call, it will throw an exception (or worse). So you must ensure you Detach(...) from the observer when you delete the Subject.
Forgetting to do this is a problem, so I like the idea of building it into the base class of the virtual destructor. This also means that the Subject has knowledge of the Observer (a reference to it) so it can call Detach(...). Which puts you into a similar situation with the Observer (i.e. if it gets deleted). The approach I have found simplest to use is to have the Observer actually be a singleton with Subjects registering for particular notifications, not just "I have some state for you to update". This is consistent with the GoF Page 298, item 7, "Specifying modifications of interest explicitly". Also, just plain makes sense to narrow the field on updates a bit. It also allows hooking up any Subject form anywhere easier.
Another case to consider is when the Subject is deleted during your Notify(..) iteration. In your Observer, you have a list of Subjects, A, B, and C. You change state and call Notify(...) on A. A deletes B. Now you move on to call Notify(...) on B, which does not exist. If you had it Detach(...) in the destructor, B may not be on the list any more. But it might still if you chose to iterate over a copy of the Subjects you started with instead of the actual list (been there, done that). Your Observer needs to handle a Detach(...) call during iteration for a Notify(...) for this reason.
I have a worked out example of this posted on a blog here.

Memory management for collections of widgets in Qt

Sorry for the dumb question, but I'm working with Qt and C++ for the first time, and working through the tutorial and some samples.
One thing that was mentioned was that Qt stuff doesn't need to be explicitly deleted. So, main question, does this also apply to collections of Qt stuff? Like say I want a dynamic number of MyWidgets, so I keep a vector or whatever of them. Are they still taken care of for me?
As a side question, what is going on to make it so I don't have to worry about destructors?
The Qt memory management model is based upon a parent-child relationship. Qt classes take an optional parent as a parameter of their constructor. The new instance registers with this parent such that it is deleted when the parent is deleted. If you are using a Qt collection (e.g. QList), I believe you can set the list as the parent of its entries. If you're using an std::vector or other collection type, you will not get "automatic" memory management.
The Qt model makes a lot of sense in a UI hierarchy where it matches one-to-one with the UI hierarchy. In other cases, it doesn't always map as cleanly and you need to evaluate whether using the Qt system makes sense for the particular situation. The normal C++ tools still work: you can use std::tr1::shared_ptr or any of the other smart pointer classes to help you manage object lifetime. Qt also includes QPointer, a guarded pointer, and the QSharedPointer/QWeakPointer pair that implement a reference-couting smart pointer and weak-reference pair.
Qt has an interesting object model for sure. When I first started it made me uneasy that there were so many new Foo calls and no deletes.
http://qt.nokia.com/doc/4.6/object.html Is a good place to start reading up on the object model.
Things of interest:
QObject subclasses have their assignment and copy-ctor methods disabled. The chain of object child-parents is maintained internally by QObject.
Generally when instantiating a QObject subclass (if you don't plan on managing its pointer yourself) you will provide another QObject pointer as the parent. This 'parent' then takes over the management of the child you just made. You can call setParent() on a QObject to change who "owns" it. There are very few methods in Qt that will change the parent of an object, and they all explicitly state that they do in the docs.
So to answer your specific question: it depends on how you made all of your MyWidget instances.
If you made each one with a parent, then no you don't have to delete them. The parent will delete them when it gets deleted.
If you're keeping a QList<MyWidget*> collection of them, and you didn't give them a parent, then you should delete them yourself.