View Full Version : PIMPL, what do I miss?
Lykurg
25th February 2011, 14:26
Hi,
lately I make myself familiar with the PIMPL idiom. And all examples do in the private declaration something like this:
#define PIMPL_DECLARE_PRIVATE(Class) \
private: \
inline Class##Private* d_func() {return reinterpret_cast<Class##Private*>(dPtr);} \
inline const Class##Private* d_func() const {return reinterpret_cast<const Class##Private*>(dPtr);} \
void* dPtr;
And assuming that you only work with normal classes: Why they all use reinterpret_cast? I don't see the need even if reinterpret_cast is cheap. What's wrong with:
#define PIMPL_DECLARE_PRIVATE(Class) \
private: \
inline Class##Private* d_func() {return dPtr;} \
inline const Class##Private* d_func() const {return const_cast<const Class##Private*>(dPtr);} \
Class##Private* dPtr;
Do I miss something important here?
franz
25th February 2011, 14:33
I'm not exactly sure what the purpose is. In pimpling, I usually don't use the macros and just take the following approach:
class MyClassPrivate;
class MyClass
{
// ...
private:
MyClassPrivate *d;
};
This suits me fine and as far as I can see has the same effect as using the above macros.
high_flyer
25th February 2011, 14:44
My guess is that its because reinterpret_cast guarantees the original type when you cast back.
wysota
25th February 2011, 15:08
I think a simple "return dPtr" would not work as "void*" and "WhatEverPrivate*" are not type-compatible. It might have worked in C but not C++. Same goes for the second cast -- there is no implicit cast between void* and other pointer types. I guess reinterpret_cast might be replaced by static_cast as well. These are just guesses though, I never understood the differences between some cast types (especially reinterpret_cast).
Lykurg
25th February 2011, 15:29
I think a simple "return dPtr" would not work as "void*" and "WhatEverPrivate*" are not type-compatible. It might have worked in C but not C++.
Yes, but therefore I would change the private pointer from void* to WhatEverPrivate* (dPtr in my case). So what I see "they" need the cast because the declare a void pointer. But if you declare direct a WhatEverPrivate pointer there is no need to cast. (only the const of course.)
@high_flyer That should only be a problem when you use dynamic_cast, because it can return a NULL pointer. But I am not sure...
@franz I want to use templates to be flexible and to add more stuff later if needed. And it not just one class.
wysota
25th February 2011, 15:43
Maybe my initial response (which I deleted and instead wrote what I have written) would be closer to truth. The reinterpret_cast might serve as a trick to have a pimpl class that does not inherit from the pimpl class of the base class of the public class.
class APrivate {};
class A {
private:
APrivate *d;
};
class BPrivate {}; // doesn't inherit APrivate
class B : public A {
private:
BPrivate *d;
};
high_flyer
25th February 2011, 15:50
a pimpl class that does not inherit from the pimpl class of the base class of the public class.
LOL.
I had to read it several times to get it!
nish
28th February 2011, 09:59
a little off-topic question but here it goes.
PIMPL says that your main class should only contain public functions and only a single private d pointer.
But how you guys handle the case when i need some *private* slots in my main class. As moc only reads .h files ( it can parse .cpp as well but i dont want that)
i need to have the private slots in my main class as well.. this makes my class a little bit more subject to change.
Qt sources solves this by declaring the private class in "*_p.h" files. But then they put a BIG warning on those private headers. But developers as we know
push the limits and include the private headers for some real hack ( there is a example of this in QtCentre Wiki as well !! )
Anyone done this differently?
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.