QPointer to QHash - qt

Is it possible to use QPointer with QHash?
QPointer<QHash<QString, QPointer<QStringList>> > pHash;

QPointer can only be used with QObject subclasses. Thus it cannot be used with QHash or QStringList, as both aren't QObject's. If the code above compiles for you, that's probably because you don't use pHash yet? Even initializing such a QPointer, e.g.
QPointer<QHash<QString, QString> > foo( new QHash<QString, QString>() );
gives errors like the following one (gcc):
error: cannot convert ‘QHash<QString, QString>*’ to ‘QObject*’ in initialization
If you really need (smart) pointers to containers, try QSharedPointer, which doesn't require the contained object to be of any specific type.
Usually one creates containers on the stack though, creating them on the heap is unidiomatic and unnecessary in almost all cases. Qt's containers are implicitly shared, thus copying them is cheap.

Related

Rcpp-Modules: Understanding .finalizer() and why it doesn't get called

I have written a Rcpp-Module named RMaxima that spawns a child process when it's constructor is called. My motivation for this question is, that I need an object of this class to be destructed, when R exits a functions execution environment in which it has been allocated and bound to a name.
Here are the important parts of my source file:
class RMaxima
{
public:
RMaxima()
{
...
// spawnes child process by instantiating an object
myMaxima = new Maxima(...);
}
~RMaxima()
{
// causes the child process to terminate properly
delete myMaxima;
}
...
private:
Maxima* myMaxima;
};
static void rmaxima_finalizer(RMaxima* ptr)
{
if (ptr)
{
delete ptr;
}
}
RCPP_MODULE(Maxima)
{
class_<RMaxima>("RMaxima")
.constructor()
.method(...)
.finalizer(&rmaxima_finalizer)
;
}
My understanding of garbage collection in R is that when the interpreter exits an environment the value bindings from this environment are thrown away and R's garbage collection frees up memory for any unbound values.
However, this seems to be different for Rcpp-Modules: If I call and exit a function that creates an instance of my class
foo <- function() {
m <- new(Rmaxima)
...
}
then, as expected, m does not appear in the global environment. However, the child process is still running. This means that my class' destructor/ finalizer has not been called. It is called however, when I quit the R session or when I install my corresponding custom package during which loading is tested.
Why? How can I cause it being destructed in a different scope? "Extending R" (Chambers, 2016) gave me some hint
The Rcpp templated type allows conversions to and from "externalptr"
with computations in the C++ code specialized to the type T of the object referred
to. Templated code can in fact use 3 parameters: type, storage scope and a final-
izer to be called when the object pointed to is deleted. The object returned to R
is in all cases of class and type "externalptr". No information is available about
the parametrized form.
as to point out that classes are returned as externalptr and protected from gc(), but I don't see the connection, since object is typeof(m): S4, i.e. a reference class.
Any further hint, where to read about this?
You are using Rcpp Modules which are in a way an alternative to using things yourself with an external pointer. Rcpp offers you Rcpp::XPtr and those are used by a few packages you could look at. (My favourite is a quick GitHub search as in this one across the 'cran' org that mirrors CRAN -- it shows over 1k code hits so some further triage needed.)
And XPtr itself seems to have an open issue in as far as guaranteed access to the finalizer is concerned; I filed issue #1108 on that last year and plan to revisit this 'soon'. But despite that issue which may be a corner case, in general this appears to work. So I would look into XPtr and/or the two helper packages for XPtr use on CRAN.
Lastly, Rcpp Classes were an extension written and contributed by John. They have not seen too much use though. Rcpp Modules is fairly widely used, and there too you could look at examples.
Lastly, you could also do something more simple and direct:
create a class Foo with an empty-ish constructor
have static pointer to a singleton of the class
create an init method to set up the class and have it hold the memory it needs
have setter/getter/worker/result methods as needed
create a teardown method to free the memory
and then call init first (maybe from package load), followed by all the work and then ensure the teardown is called. It's a far-from-perfect design (maybe teardown is not called?) but the simplicity gives you a comparison. And once you have the fragments you can build fancier structures on top.

Can I retain ownership of QObjects passed to QJSEngine?

I'm using QJSEngine and binding some objects with engine.globalObject().setProperty(name, engine.newQObject(obj));
The problem is that QJSEngine destructor is calling the destructors of those objects but I want them to outlive the QJSEngine object.
This happens even if I remove the property from globalObject().
Looks like using QQmlEngine instead of QJSEngine gives access to setObjectOwnership which allows to work around the issue.
https://doc.qt.io/qt-5/qqmlengine.html#setObjectOwnership
From what I understand from the docs though, it will still be an issue with objects returned from Q_INVOKABLE methods, which I'm not sure how to retain ownership of. So if anyone has some ideas, I'd like to know them.

What's the point of unique_ptr?

Isn't a unique_ptr essentially the same as a direct instance of the object? I mean, there are a few differences with dynamic inheritance, and performance, but is that all unique_ptr does?
Consider this code to see what I mean. Isn't this:
#include <iostream>
#include <memory>
using namespace std;
void print(int a) {
cout << a << "\n";
}
int main()
{
unique_ptr<int> a(new int);
print(*a);
return 0;
}
Almost exactly the same as this:
#include <iostream>
#include <memory>
using namespace std;
void print(int a) {
cout << a << "\n";
}
int main()
{
int a;
print(a);
return 0;
}
Or am I misunderstanding what unique_ptr should be used for?
In addition to cases mentioned by Chris Pitman, one more case you will want to use std::unique_ptr is if you instantiate sufficiently large objects, then it makes sense to do it in the heap, rather than on a stack. The stack size is not unlimited and sooner or later you might run into stack overflow. That is where std::unique_ptr would be useful.
The purpose of std::unique_ptr is to provide automatic and exception-safe deallocation of dynamically allocated memory (unlike a raw pointer that must be explicitly deleted in order to be freed and that is easy to inadvertently not get freed in the case of interleaved exceptions).
Your question, though, is more about the value of pointers in general than about std::unique_ptr specifically. For simple builtin types like int, there generally is very little reason to use a pointer rather than simply passing or storing the object by value. However, there are three cases where pointers are necessary or useful:
Representing a separate "not set" or "invalid" value.
Allowing modification.
Allowing for different polymorphic runtime types.
Invalid or not set
A pointer supports an additional nullptr value indicating that the pointer has not been set. For example, if you want to support all values of a given type (e.g. the entire range of integers) but also represent the notion that the user never input a value in the interface, that would be a case for using a std::unique_ptr<int>, because you could get whether the pointer is null or not as a way of indicating whether it was set (without having to throw away a valid value of integer just to use that specific value as an invalid, "sentinel" value denoting that it wasn't set).
Allowing modification
This can also be accomplished with references rather than pointers, but pointers are one way of doing this. If you use a regular value, then you are dealing with a copy of the original, and any modifications only affect that copy. If you use a pointer or a reference, you can make your modifications seen to the owner of the original instance. With a unique pointer, you can additionally be assured that no one else has a copy, so it is safe to modify without locking.
Polymorphic types
This can likewise be done with references, not just with pointers, but there are cases where due to semantics of ownership or allocation, you would want to use a pointer to do this... When it comes to user-defined types, it is possible to create a hierarchical "inheritance" relationship. If you want your code to operate on all variations of a given type, then you would need to use a pointer or reference to the base type. A common reason to use std::unique_ptr<> for something like this would be if the object is constructed through a factory where the class you are defining maintains ownership of the constructed object. For example:
class Airline {
public:
Airline(const AirplaneFactory& factory);
// ...
private:
// ...
void AddAirplaneToInventory();
// Can create many different type of airplanes, such as
// a Boeing747 or an Airbus320
const AirplaneFactory& airplane_factory_;
std::vector<std::unique_ptr<Airplane>> airplanes_;
};
// ...
void Airline::AddAirplaneToInventory() {
airplanes_.push_back(airplane_factory_.Create());
}
As you mentioned, virtual classes are one use case. Beyond that, here are two others:
Optional instances of objects. My class may delay instantiating an instance of the object. To do so, I need to use memory allocation but still want the benefits of RAII.
Integrating with C libraries or other libraries that love returning naked pointers. For example, OpenSSL returns pointers from many (poorly documented) methods, some of which you need to cleanup. Having a non-copyable pointer container is perfect for this case, since I can protect it as soon as it is returned.
A unique_ptr functions the same as a normal pointer except that you do not have to remember to free it (in fact it is simply a wrapper around a pointer). After you allocate the memory, you do not have to afterwards call delete on the pointer since the destructor on unique_ptr takes care of this for you.
Two things come to my mind:
You can use it as a generic exception-safe RAII wrapper. Any resource that has a "close" function can be wrapped with unique_ptr easily by using a custom deleter.
There are also times you might have to move a pointer around without knowing its lifetime explicitly. If the only constraint you know is uniqueness, then unique_ptr is an easy solution. You could almost always do manual memory management also in that case, but it is not automatically exception safe and you could forget to delete. Or the position you have to delete in your code could change. The unique_ptr solution could easily be more maintainable.

Using QObject instead of a container

After reading up on the interesting parent-child system of QObject I am wondering how common it is for Qt developers to use this in place of a more traditional container. Assuming memory contiguity is not a requirement, it seems this offers some interesting features.
For example, you could have a QObject and give it children of different types, and then find all children easily based on their types, giving QObject a dynamic heterogenous container-like feature, as opposed to the required homogenous collection of a traditional container.
And QObject naturally manages the memory of its children, which is convenient as well.
Is this a common use of this feature?
QObject::findChildren could be much slower than storing your objects in a normal container like QList because:
It iterates over all children each time. It even searches recursively (but this can be disabled).
It performs runtime type check.
It constructs new QList each time. This can be slow and expensive it there are many objects in result.
All the above it unnecessary if you just use QList<Type*> my_objects. Also in this case:
You can name your collection. QList<QPushButton*> panic_buttons is clearer than findChildren<QPushButton*>().
You can have several collections of objects of the same type.
If you want to make a heterogenous container, you can use QHash<any_type_identifier, QObject*>. It will be faster.
Maybe, findChildren approach may be simplier sometimes. But if you have many objects or a complicated class, you'd better use normal containers. You can still use QObject's memory management with them without any problems.
As #PavelStrakhov states, using QObject::findChildren could be slower. However, one method I use is to combine storing objects in QList as well as having the QObject parent hierarchy. It's based on doing something like this: -
class BaseObject : public QObject
{
Q_OBJECT
public:
static BaseObject* FindObject(unsigned int id); // find object by id
private:
unsigned int m_id;
static unsigned int s_nextId; // next id for a new BaseObject
static QList<QBaseObject*> s_objectsList; // list of all BaseObject-type instances
};
All objects now inherit BaseObject instead of QObject. When a new class is created, the constructor of the BaseObject will set the item's id, increment s_nextId and finally, the object is added to s_objectsList. Finding objects is now a simple matter of searching the static object list.
This may not suit the design of the application that you're developing, but it certainly helped me, especially when using the QGraphicsView / QGraphicsScene system. In that situation, the BaseObject is derived from QGraphicsObject.
Of-course, if you're using a lot of standard widgets, you're less likely to want to create new classes for them all, but it's an option that can suit some designs.

Storing pointers using QListWidgetItem::setData

I have a QListWidget of calendars. Each QListWidgetItem is logically associated with an instance of Calendar, which is a class that belongs to the Model side of the application.
Can I store this association in the form of a pointer using QListWidgetItem::setData? When I attempt to do this, I get the following error:
error: 'QVariant::QVariant(void*)' is private
There is another constructor for void*: QVariant::QVariant(int typeOrUserType, const void * copy) where you should pass an unique integer to represent the pointer type.
But as stated by the documentation, you could declare your pointer type with Q_DECLARE_METATYPE(Calendar*) and use QVariant::fromValue<Calendar*>(...) and QVariant::value<Calendar*>() to store and retrieve the value.
Or instead, because you are using a QListWidget instead of a regular model, you can just subclass QListWidgetItem, and add a Calendar* member variable with the required accessors, to avoid the overhead of using QVariant.
I would suggest looking at this solution as well, which I think is quite elegant:
(there are minor syntax errors, but you will spot them quickly or the compiler will issue an error)
https://web.archive.org/web/20171025163314/http://blog.bigpixel.ro/2010/04/storing-pointer-in-qvariant/

Resources