QObject set/get property with index operator - c++

Why didn't Qt set/get properties through the index operator [] ?
Is there any good reason for this that I don't know about?
Thanks.

I don't see any clear benefit to using the indexing operator, but here is a major downside:
Qt objects are usually referenced using pointer (ie. QWidget*). If Qt used operators for accessing properties, it would be very easy to end up using the indexing operator on the pointer Consider the following:
void doSomethingWithProperty(QWidget* widget) {
auto& propertyValue = widget[0];
}
propertyValue here would not be the result of the indexing operator on QWidget/QObject if there was one because we can treat pointers like arrays in C/C++ (note that this is sometimes considered a bad practice). It would be a reference to the widget. To instead call the operator on the type, you would need something like (*widget)[0] which is not nice to write.
Maybe you use strings for the operator parameter... but then it isn't clear to me what the operator does. Qt objects have child objects. Does (*widget)["thing"] return a property named thing or does if find a child object named thing? It is not obvious to me which one it should be.

Related

Overload [] C++ operator for complex data-structure

what I plan to do: I have a own container-structure. But it should not store all elements, but only some with special properties, while others can be created dynamically from the information in the stucture.
Thus I have a insert(ITEM* i) method, that checks, whether i needs to be stored explicitly and is then stored into a map, or of it can be reconstructed dynamically. Then only the information that the item was added is stored.
The same for a ITEM* get(ITEMINDEX idx) method. It checks whether the ITEM belonging to idx is stored explicitly. If yes, it is read from the internal map and the pointer returned. If it is registered, but implicitly stored, the ITEM is created dynamically and returned.
In order to be compatible with other structures in the code, I planned to overload the [] operator, but I don't know how to approach this or if this is even possible for this more complex structure.
Is it possible and if yes, how?
Thanks in advance!
Update
Nims code works. But I recognised a problem now (although it was obvious from the beginning...): If get() finds a entry the pointer is returned by []. If it is not stored, the ITEM is constructed and the pointer returned. But the RAM is never released, because the algorithm that uses the container cannot distinguish between saved an constructed ITEMS to delete the second kind.
If you would like to provide operator[] for your object you have to answer your self if following code makes sense:
MyObj obj;
/*1*/ obj[some_index] = new_object;
/*2*/ Obj& some_object = obj[some_index];
what semantics would be for case 1 - you say: it should insert some value into your class but, you add new data with insert(ITEM* i) (no some_index provided here), so you should prohibit usage of your class as in case of 1.
Now for case 2, in your example you show that ITEM* get(ITEMINDEX idx), so your class client code must know what is ITEMINDEX, so it looks like case 2 would be ok.
The problem is IMO only with case 1, and inserting new data with operator[]. If you look at the std::map container then you have no problem with both above cases. Users of you class will want to use it in similar way to std::map operator[], if its functionality will differ it will cause confusion.
A C++ class operator is a method with a weird name. It can do whatever you wish, provided it has the expected weird name. In the case of operator [], it looks like
template <typename T>
T& operator[](std::size_t idx) { /* arbitrary code */ };
That's about all there is to it really.
This interface is quite constrained. You'll get an index and need to produce a reference to an instance of your class in response. You can return a reference to something with unusual ideas about assignment, e.g. on assignment it does some checking with a data structure accessed via an internal pointer. There may be a lot of incidental complexity down this path.

Overloading bracket assignment in C++

I am in the process of porting an Objective-C application to C++ and I decided to create a class similar to NSObject and NSDictionary. If you are unfamiliar with this system, an NSObject is an object which all objects inherit form in Obj-C and then there is a reference counting mechanism within it. When there are no more references, the object frees itself.
In my code, I would like to be able to do the following
CMDictionary["Key"] = Object;
Internally, this is stored as
Map<string, CMObject*> mDictionary
Whenever a new object is assigned into the object, the dictionary must then retain this object by calling its retain function as well as calling release on any object that this new object might have replaced. My problem stems from the fact that I cannot find anyway to run code and determine when the brackets are being used in an assignment as I would not want the retain function to be called when I wrote something like
CMDicionary["key"]->StringValue();
Would there by anyway to do this, or would I need to just use getter/setter functions to modify my dictionary
What you typically do in this situation is to implement:
Object const& Map::operator[](string) const;
Object& Map::operator[](string);
Note that I wrote Object& instead of Object. You can at any rate instantiate a new Object and hand it out, relying on a proper Object& Object::operator=(Object const&) to be implemented, which will then perform the assignment, after your Map::operator[] function returns (don't worry, the compiler will optimise it away in most cases).
You should overload the operator[] to accept a string.
http://courses.cms.caltech.edu/cs11/material/cpp/donnie/cpp-ops.html
Consider writing a new class similar to shared_ptr<CMObject*> and do the retain/release inside of that object.

private object pointer vs object value, and returning object internals

Related to: C++ private pointer "leaking"?
According to Effective C++ (Item 28), "avoid returning handles (references, pointers, or iterators) to object internals. It increases encapsulation, helps const member functions act const, and minimizes the creation of dangling handles."
Returning objects by value is the only way I can think of to avoid returning handles. This to me suggests I should return private object internals by value as much as possible.
However, to return object by value, this requires the copy constructor which goes against the Google C++ Style Guide of "DISALLOW_COPY_AND_ASSIGN" operators.
As a C++ newbie, unless I am missing something, I find these two suggestions to conflict each other.
So my questions are: is there no silver bullet which allows efficient reference returns to object internals that aren't susceptible to dangling pointers? Is the const reference return as good as it gets? In addition, should I not be using pointers for private object fields that often? What is a general rule of thumb for choosing when to store private instance fields of objects as by value or by pointer?
(Edit) For clarification, Meyers' example dangling pointer code:
class Rectangle {
public:
const Point& upperLeft() const { return pData->ulhc; }
const Point& lowerRight() const { return pData->lrhc; }
...
};
class GUIObject { ... };
const Rectangle boundingBox(const GUIObject& obj);
If the client creates a function with code such as:
GUIObject *pgo; // point to some GUIObject
const Point *pUpperLeft = &(boundingBox(*pgo).upperLeft());
"The call to boundingBox will return a new, temporary Rectangle object [(called temp from here.)] upperLeft will then be called on temp, and that call will return a reference to an internal part of temp, in particular, to one of the Points making it up...at the end of the statement, boundingBox's return value temp will be destroyed, and that will indirectly lead to the destruction of temp's Points. That, in turn, will leave pUpperLeft pointing to an object that no longer exists." Meyers, Effective C++ (Item 28)
I think he is suggesting to return Point by value instead to avoid this:
const Point upperLeft() const { return pData->ulhc; }
The Google C++ style guide is, shall we say, somewhat "special" and has led to much discussion on various C++ newsgroups. Let's leave it at that.
Under normal circumstances I would suggest that following the guidelines in Effective C++ is generally considered to be a good thing; in your specific case, returning an object instead of any sort of reference to an internal object is usually the right thing to do. Most compilers are pretty good at handling large return values (Google for Return Value Optimization, pretty much every compiler does it).
If measurements with a profiler suggest that returning a value is becoming a bottleneck, then I would look at alternative methods.
First, let's look at this statement in context:
According to Effective C++ (Item 28),
"avoid returning handles (references,
pointers, or iterators) to object
internals. It increases encapsulation,
helps const member functions act
const, and minimizes the creation of
dangling handles."
This is basically talking about a class's ability to maintain invariants (properties that remain unchanged, roughly speaking).
Let's say you have a button widget wrapper, Button, which stores an OS-specific window handle to the button. If the client using the class had access to the internal handle, they could tamper with it using OS-specific calls like destroying the button, making it invisible, etc. Basically by returning this handle, your Button class sacrifices any control it originally had over the button handle.
You want to avoid these situations in such a Button class by providing everything you can do with the button as methods in this Button class. Then you don't need to ever return a handle to the OS-specific button handle.
Unfortunately, this doesn't always work in practice. Sometimes you have to return the handle or pointer or some other internal by reference for various reasons. Let's take boost::scoped_ptr, for instance. It is a smart pointer designed to manage memory through the internal pointer it stores. It has a get() method which returns this internal pointer. Unfortunately, that allows clients to do things like:
delete my_scoped_ptr.get(); // wrong
Nevertheless, this compromise was required because there are many cases where we are working with C/C++ APIs that require regular pointers to be passed in. Compromises are often necessary to satisfy libraries which don't accept your particular class but does accept one of its internals.
In your case, try to think if your class can avoid returning internals this way by instead providing functions to do everything one would want to do with the internal through your public interface. If not, then you've done all you can do; you'll have to return a pointer/reference to it but it would be a good habit to document it as a special case. You should also consider using friends if you know which places need to gain access to the class's internals in advance; this way you can keep such accessor methods private and inaccessible to everyone else.
Returning objects by value is the only
way I can think of to avoid returning
handles. This to me suggests I should
return private object internals by
value as much as possible.
No, if you can return a copy, then you can equally return by const reference. The clients cannot (under normal circumstances) tamper with such internals.
It really depends on the situation. If you plan to see changes in the calling method you want to pass by reference. Remember that passing by value is a pretty heavy operation. It requires a call to the copy constructor which in essence has to allocate and store enough memory to fit size of your object.
One thing you can do is fake pass by value. What that means is pass the actual parameter by value to a method that accepts const your object. This of course means the caller does not care to see changes to your object.
Try to limit pass by value if you can unless you have to.

Best Practice: QT4 QList<Mything*>... on Heap, or QList<Mything> using reference?

Learning C++, so be gentle :)...
I have been designing my application primarily using heap variables (coming from C), so I've designed structures like this:
QList<Criteria*> _Criteria;
// ...
Criteria *c = new Criteria(....);
_Criteria.append(c);
All through my program, I'm passing pointers to specific Criteria, or often the list. So, I have a function declared like this:
QList<Criteria*> Decision::addCriteria(int row,QString cname,QString ctype);
Criteria * Decision::getCriteria(int row,int col)
which inserts a Criteria into a list, and returns the list so my GUI can display it.
I'm wondering if I should have used references, somehow. Since I'm always wanting that exact Criteria back, should I have done:
QList<Criteria> _Criteria;
// ....
Criteria c(....);
_Criteria.append(c);
...
QList<Criteria>& Decision::addCriteria(int row,QString cname,QString ctype);
Criteria& Decision::getCriteria(int row,int col)
(not sure if the latter line is syntactically correct yet, but you get the drift).
All these items are specific, quasi-global items that are the core of my program.
So, the question is this: I can certainly allocate/free all my memory w/o an issue in the method I'm using now, but is there are more C++ way? Would references have been a better choice (it's not too late to change on my side).
TIA
Mike
I would return QList<Criteria> as a plain value. QList is one of Qt's shared classes, meaning that its internal representation is shared between multiple instances so long as none of them are modified.
If the Criteria class is fairly complex, such that an incidental copy made because one of the lists is modified at some point incurs noticable overhead, then I would use QSharedData in the implementation of Criteria so that it, too, is only copied as needed.
This approach has two downsides: one, the copying, if any, is implicit and may happen when you don't expect it to, and two, it doesn't allow for polymorphic use of Criteria. If you have Criteria as the root of a class hierarchy, then you must use pointers. In that case, I would use shared_ptr from Boost or C++ TR1 to avoid memory management hassles, or make Critera inherit publicly from QObject and make all Critera objects children of Decision.
I don't think references would be a better choice. If you are dynamically allocating these objects, you still need keep a copy of the pointer around to delete later. Plus, when passing around pointers you don't have to worry about copy constructors or an implicit sharing technique like QSharedData. You'll still get "that exact Criteria back".
My advice is: Unless you have a really good reason to make things more complex, keep it simple.
However, from a Qt standpoint you should generally not pass around pointers or references to Qt objects. These objects do use implicit sharing so they don't act like "normal" C++ objects. If you are still learning C++ I'd suggest leaving this technique out of your own code for now. But to use Qt effectively you need to understand how it works so I recommend reading more about it here:
http://qt.nokia.com/doc/4.6/implicit-sharing.html
Good luck!
EDIT:
One thing I forgot to mention. If you know you don't want you class to be copied, you can enforce this by declaring a private copy constructor and operator= overload:
class A
{
//Code goes here
private:
A(const A&);
A& operator=(const A&);
};

What you think about throwing an exception for not found in C++?

I know most people think that as a bad practice but when you are trying to make your class public interface only work with references, keeping pointers inside and only when necessary, I think there is no way to return something telling that the value you are looking doesn't exist in the container.
class list {
public:
value &get(type key);
};
Let's think that you don't want to have dangerous pointers being saw in the public interface of the class, how do you return a not found in this case, throwing an exception?
What is your approach to that? Do you return an empty value and check for the empty state of it? I actually use the throw approach but I introduce a checking method:
class list {
public:
bool exists(type key);
value &get(type key);
};
So when I forget to check that the value exists first I get an exception, that is really an exception.
How would you do it?
The STL deals with this situation by using iterators. For example, the std::map class has a similar function:
iterator find( const key_type& key );
If the key isn't found, it returns 'end()'. You may want to use this iterator approach, or to use some sort of wrapper for your return value.
The correct answer (according to Alexandrescu) is:
Optional and Enforce
First of all, do use the Accessor, but in a safer way without inventing the wheel:
boost::optional<X> get_X_if_possible();
Then create an enforce helper:
template <class T, class E>
T& enforce(boost::optional<T>& opt, E e = std::runtime_error("enforce failed"))
{
if(!opt)
{
throw e;
}
return *opt;
}
// and an overload for T const &
This way, depending on what might the absence of the value mean, you either check explicitly:
if(boost::optional<X> maybe_x = get_X_if_possible())
{
X& x = *maybe_x;
// use x
}
else
{
oops("Hey, we got no x again!");
}
or implicitly:
X& x = enforce(get_X_if_possible());
// use x
You use the first way when you’re concerned about efficiency, or when you want to handle the failure right where it occurs. The second way is for all other cases.
The problem with exists() is that you'll end up searching twice for things that do exist (first check if it's in there, then find it again). This is inefficient, particularly if (as its name of "list" suggests) your container is one where searching is O(n).
Sure, you could do some internal caching to avoid the double search, but then your implementation gets messier, your class becomes less general (since you've optimised for a particular case), and it probably won't be exception-safe or thread-safe.
Don't use an exception in such a case. C++ has a nontrivial performance overhead for such exceptions, even if no exception is thrown, and it additially makes reasoning about the code much harder (cf. exception safety).
Best-practice in C++ is one of the two following ways. Both get used in the STL:
As Martin pointed out, return an iterator. Actually, your iterator can well be a typedef for a simple pointer, there's nothing speaking against it; in fact, since this is consistent with the STL, you could even argue that this way is superior to returning a reference.
Return a std::pair<bool, yourvalue>. This makes it impossible to modify the value, though, since a copycon of the pair is called which doesn't work with referende members.
/EDIT:
This answer has spawned quite some controversy, visible from the comments and not so visible from the many downvotes it got. I've found this rather surprising.
This answer was never meant as the ultimate point of reference. The “correct” answer had already been given by Martin: execeptions reflect the behaviour in this case rather poorly. It's semantically more meaningful to use some other signalling mechanism than exceptions.
Fine. I completely endorse this view. No need to mention it once again. Instead, I wanted to give an additional facet to the answers. While minor speed boosts should never be the first rationale for any decision-making, they can provide further arguments and in some (few) cases, they may even be crucial.
Actually, I've mentioned two facets: performance and exception safety. I believe the latter to be rather uncontroversial. While it's extremely hard to give strong exceptions guarantees (the strongest, of course, being “nothrow”), I believe it's essential: any code that is guaranteed to not throw exceptions makes the whole program easier to reason about. Many C++ experts emphasize this (e.g. Scott Meyers in item 29 of “Effective C++”).
About speed. Martin York has pointed out that this no longer applies in modern compilers. I respectfully disagree. The C++ language makes it necessary for the environment to keep track, at runtime, of code paths that may be unwound in the case of an exception. Now, this overhead isn't really all that big (and it's quite easy to verify this). “nontrivial” in my above text may have been too strong.
However, I find it important to draw the distinction between languages like C++ and many modern, “managed” languages like C#. The latter has no additional overhead as long as no exception is thrown because the information necessary to unwind the stack is kept anyway. By and large, stand by my choice of words.
STL Iterators?
The "iterator" idea proposed before me is interesting, but the real point of iterators is navigation through a container. Not as an simple accessor.
If you're accessor is one among many, then iterators are the way to go, because you will be able to use them to move in the container. But if your accessor is a simple getter, able to return either the value or the fact there is no value, then your iterator is perhaps only a glorified pointer...
Which leads us to...
Smart pointers?
The point of smart pointers is to simplify pointer ownership. With a shared pointer, you'll get a ressource (memory) which will be shared, at the cost of an overhead (shared pointers needs to allocate an integer as a reference counter...).
You have to choose: Either your Value is already inside a shared pointer, and then, you can return this shared pointer (or a weak pointer). Or Your value is inside a raw pointer. Then you can return the row pointer. You don't want to return a shared pointer if your ressource is not already inside a shared pointer: A World of funny things will happen when your shared pointer will get out of scope an delete your Value without telling you...
:-p
Pointers?
If your interface is clear about its ownership of its ressources, and by the fact the returned value can be NULL, then you could return a simple, raw pointer. If the user of your code is dumb enough ignore the interface contract of your object, or to play arithmetics or whatever with your pointer, then he/she will be dumb enough to break any other way you'll choose to return the value, so don't bother with the mentally challenged...
Undefined Value
Unless your Value type really has already some kind of "undefined" value, and the user knows that, and will accept to handle that, it is a possible solution, similar to the pointer or iterator solution.
But do not add a "undefined" value to your Value class because of the problem you asked: You'll end up raising the "references vs. pointer" war to another level of insanity. Code users want the objects you give them to either be Ok, or to not exist. Having to test every other line of code this object is still valid is a pain, and will complexify uselessly the user code, by your fault.
Exceptions
Exceptions are usually not as costly as some people would like them to be. But for a simple accessor, the cost could be not trivial, if your accessor is used often.
For example, the STL std::vector has two accessors to its value through an index:
T & std::vector::operator[]( /* index */ )
and:
T & std::vector::at( /* index */ )
The difference being that the [] is non-throwing . So, if you access outside the range of the vector, you're on your own, probably risking memory corruption, and a crash sooner or later. So, you should really be sure you verified the code using it.
On the other hand, at is throwing. This means that if you access outside the range of the vector, then you'll get a clean exception. This method is better if you want to delegate to another code the processing of an error.
I use personnaly the [] when I'm accessing the values inside a loop, or something similar. I use at when I feel an exception is the good way to return the current code (or the calling code) the fact something went wrong.
So what?
In your case, you must choose:
If you really need a lightning-fast access, then the throwing accessor could be a problem. But this means you already used a profiler on your code to determinate this is a bottleneck, doesn't it?
;-)
If you know that not having a value can happen often, and/or you want your client to propagate a possible null/invalid/whatever semantic pointer to the value accessed, then return a pointer (if your value is inside a simple pointer) or a weak/shared pointer (if your value is owned by a shared pointer).
But if you believe the client won't propagate this "null" value, or that they should not propagate a NULL pointer (or smart pointer) in their code, then use the reference protected by the exception. Add a "hasValue" method returning a boolean, and add a throw should the user try the get the value even if there is none.
Last but not least, consider the code that will be used by the user of your object:
// If you want your user to have this kind of code, then choose either
// pointer or smart pointer solution
void doSomething(MyClass & p_oMyClass)
{
MyValue * pValue = p_oMyClass.getValue() ;
if(pValue != NULL)
{
// Etc.
}
}
MyValue * doSomethingElseAndReturnValue(MyClass & p_oMyClass)
{
MyValue * pValue = p_oMyClass.getValue() ;
if(pValue != NULL)
{
// Etc.
}
return pValue ;
}
// ==========================================================
// If you want your user to have this kind of code, then choose the
// throwing reference solution
void doSomething(MyClass & p_oMyClass)
{
if(p_oMyClass.hasValue())
{
MyValue & oValue = p_oMyClass.getValue() ;
}
}
So, if your main problem is choosing between the two user codes above, your problem is not about performance, but "code ergonomy". Thus, the exception solution should not be put aside because of potential performance issues.
:-)
Accessor?
The "iterator" idea proposed before me is interesting, but the real point of iterators is navigation through a container. Not as an simple accessor.
I agree with paercebal, an iterator is to iterate. I don't like the way STL does. But the idea of an accessor seems more appealing. So what we need? A container like class that feels like a boolean for testing but behaves like the original return type. That would be feasible with cast operators.
template <T> class Accessor {
public:
Accessor(): _value(NULL)
{}
Accessor(T &value): _value(&value)
{}
operator T &() const
{
if (!_value)
throw Exception("that is a problem and you made a mistake somewhere.");
else
return *_value;
}
operator bool () const
{
return _value != NULL;
}
private:
T *_value;
};
Now, any foreseeable problem? An example usage:
Accessor <type> value = list.get(key);
if (value) {
type &v = value;
v.doSomething();
}
How about returning a shared_ptr as the result. This can be null if the item wasn't found. It works like a pointer, but it will take care of releasing the object for you.
(I realize this is not always the right answer, and my tone a bit strong, but you should consider this question before deciding for other more complex alternatives):
So, what's wrong with returning a pointer?
I've seen this one many times in SQL, where people will do their earnest to never deal with NULL columns, like they have some contagious decease or something. Instead, they cleverly come up with a "blank" or "not-there" artificial value like -1, 9999 or even something like '#X-EMPTY-X#'.
My answer: the language already has a construct for "not there"; go ahead, don't be afraid to use it.
what I prefer doing in situations like this is having a throwing "get" and for those circumstances where performance matter or failiure is common have a "tryGet" function along the lines of "bool tryGet(type key, value **pp)" whoose contract is that if true is returned then *pp == a valid pointer to some object else *pp is null.
#aradtke, you said.
I agree with paercebal, an iterator is
to iterate. I don't like the way STL
does. But the idea of an accessor
seems more appealing. So what we need?
A container like class that feels like
a boolean for testing but behaves like
the original return type. That would
be feasible with cast operators. [..] Now,
any foreseeable problem?
First, YOU DO NOT WANT OPERATOR bool. See Safe Bool idiom for more info. But about your question...
Here's the problem, users need to now explict cast in cases. Pointer-like-proxies (such as iterators, ref-counted-ptrs, and raw pointers) have a concise 'get' syntax. Providing a conversion operator is not very useful if callers have to invoke it with extra code.
Starting with your refence like example, the most concise way to write it:
// 'reference' style, check before use
if (Accessor<type> value = list.get(key)) {
type &v = value;
v.doSomething();
}
// or
if (Accessor<type> value = list.get(key)) {
static_cast<type&>(value).doSomething();
}
This is okay, don't get me wrong, but it's more verbose than it has to be. now consider if we know, for some reason, that list.get will succeed. Then:
// 'reference' style, skip check
type &v = list.get(key);
v.doSomething();
// or
static_cast<type&>(list.get(key)).doSomething();
Now lets go back to iterator/pointer behavior:
// 'pointer' style, check before use
if (Accessor<type> value = list.get(key)) {
value->doSomething();
}
// 'pointer' style, skip check
list.get(key)->doSomething();
Both are pretty good, but pointer/iterator syntax is just a bit shorter. You could give 'reference' style a member function 'get()'... but that's already what operator*() and operator->() are for.
The 'pointer' style Accessor now has operator 'unspecified bool', operator*, and operator->.
And guess what... raw pointer meets these requirements, so for prototyping, list.get() returns T* instead of Accessor. Then when the design of list is stable, you can come back and write the Accessor, a pointer-like Proxy type.
Interesting question. It's a problem in C++ to exclusively use references I guess - in Java the references are more flexible and can be null. I can't remember if it's legal C++ to force a null reference:
MyType *pObj = nullptr;
return *pObj
But I consider this dangerous. Again in Java I'd throw an exception as this is common there, but I rarely see exceptions used so freely in C++.
If I was making a puclic API for a reusable C++ component and had to return a reference, I guess I'd go the exception route.
My real preference is to have the API return a pointer; I consider pointers an integral part of C++.