The first official SoC week is gone! A bit of a hard work, but good results obtained…
With the last smartsave commit, all the stubs are done and real code is coming out: all the base classes are being populated, and in a few days some UI may come up.
I’m especially working in the save part of the system, still from the backend point of view, with models and signals that come and go through the classes (test 2 already shows something of this), updating views when new annotations come up. A hard link to the annotation framework (in playground) is coming out, and probably one of the two exposed classes will be collapsed to that framework, when my experiments and my messing up the API will stabilize a little.
The most difficult part, I must admit, has been to adapt to Qt frameworks (signal-slot, model-view, d-pointers), which are pretty different from my last C++ works or from the Java approach, so a big thank goes to Sebastian Trueg for his advices on them.
Besides, I hope not to flame in any way, but I really have some difficulties in understanding why the d-pointer idea… for example, I see the model-view as some kind of a derivative of MVC, and signal-slot as an alternative to a callback system; I see why calling getter methods with the variable name (C# does something similar), but why can’t I put my private members directly in the class? I read about the binary compatibility, but those are still private members, so the outside world cannot see them. So why complicate the classes structure with all those private classes with public members?
So, C++/Qt masters, I’d really like to read your opinion on that, not for flaming (I repeat), just for deeply understanding this way of programming 🙂
And, stay tuned for UI updates in the next few days!
The thing about binary compatibility is how things appear in RAM. Although access to a private member is restricted by C++, it still takes space in memory. If you add private members to a class, it will take up more space in memory. This can result in other members having different offsets in memory; remember, when C++ gets compiled things are no longer referenced by name, but by address and offset. Having a private member class allows you to change the private class without changing the size and offsets of the members of the base class. That means that publicly accessible members will still be at the same offsets, and so new code can still link against an old binary. Hope that clarifies things a little – I’m not always the best at explaining things clearly.
It’s all about binary compatibility, which is described here:
http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B
dptrs are primarily useful for public APIs.
Ok, it is a bit more clear now, I was not thinking to the memory address of the library functions…
Those d-ptr stuff has some very neat benefits if you have big projects. Since the private classes are not defined in the public header it is less likely that you change the public headers if you make implementation changes on some class because most stuff will only touch the .cpp and _p.h files. At the end you will get one file moc’ed, the .cpp compiled and everything linked instead of everything recompiled that uses the class.
So: how should the file structure be? Public class declaration in class.h, private declaration in class_p.h, both implementations in class.cpp?
By the way, if you fell more confortable using the private members.. just do it. You’ll have plenty of time later to do the “private counterpart” of your class, and you’ll do it only if you want to achieve BC…
*mind the over-engineering* 😉
BC?
“BC” == “binary compatibility”
another nice benefit of d-pointers, IMO, is that your getters can have the same name as the name you gave to the private class’s member.
this way, you won’t end up giving ugly names like m_string just to be able to call your getter string().
Signals and slots are not just an alternative to callbacks, it’s a whole concept that throws the callback one into the dust. Signals and slots are thread safe, type safe at runtime, work over DBus and pretty much anything, and turning a function into a slot is just a matter of writing 2 lines in the header.
Having used C# myself, I can surely tell that its event system is really weak compared to Qt’s Sigs/Slots (check my old blog entries to compare), but it takes some time to get full appreciation on it.
Also, Model/View is a bit different from C# (WPF) approach, and a bit easier.
@drf: well, I must admit that my comparison is with Java (I haven’t used C# enough to say something about it), and after a few years with the latter and a few weeks with Qt, I still prefer callbacks… 🙂
But hey, it’s just a matter of getting comfortable with signals and slots…