/
Pimp My Pimpl.html
1257 lines (1078 loc) · 77.8 KB
/
Pimp My Pimpl.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head profile="http://gmpg.org/xfn/11">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Pimp My Pimpl | -Wmarc</title>
<link rel="pingback" href="https://marcmutz.wordpress.com/xmlrpc.php" />
<link rel="alternate" type="application/rss+xml" title="-Wmarc » Feed" href="https://marcmutz.wordpress.com/feed/" />
<link rel="alternate" type="application/rss+xml" title="-Wmarc » Comments Feed" href="https://marcmutz.wordpress.com/comments/feed/" />
<link rel="alternate" type="application/rss+xml" title="-Wmarc » Pimp My Pimpl Comments Feed" href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/feed/" />
<script type="text/javascript">
/* <![CDATA[ */
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function () {
oldonload();
func();
}
}
}
/* ]]> */
</script>
<link rel='stylesheet' id='all-css-0' href='https://s2.wp.com/_static/??-eJx9kd1qwzAMRl9onhgLKbsYexbHUV2ltiX8Q+jbV1nY1pLhG6FPnIMEglWM41QxVYjNSGieUoESKeBNMi/o6nN6daW8wP9aoCsWWLCKdVfznQ74FNj/Cew9ztyqOXMIvMJKs8fuDscZdR7F1o2IOJPFgFGxnhZl/LG29qIHHm974FdR2kyTZCzFaI3UoqkXXXT09jFIm0AjZslUEEq9BeztwMgL7XXHCBJXUrL8Nj3fI5vAzlbi9BTMOVjKPTXj9gdtPSj1EDfpK36+DcPH+H4aT8NyBxmtzhs=' type='text/css' media='all' />
<link rel='stylesheet' id='print-css-1' href='https://s1.wp.com/wp-content/mu-plugins/global-print/global-print.css?m=1444132114g' type='text/css' media='print' />
<link rel='stylesheet' id='all-css-2' href='https://s2.wp.com/_static/??-eJx9jEsOwjAMRC+EMZUilS4QZwmNcYzyU+yq12+RYMVnNU+aeYNrg7kWo2KYF2hpYSmKrarBPXnpqNF3KfzO46x6wO8WU6Eue/EDP1yLlEkxOuRUbz79O18lMJniPnkxcJcAvgRIovZ0r/kyODeNp3E4T48NEuFRhQ==' type='text/css' media='all' />
<script type='text/javascript'>
/* <![CDATA[ */
var LoggedOutFollow = {"invalid_email":"Your subscription did not succeed, please try again with a valid email address."};
/* ]]> */
</script>
<script type='text/javascript' src='https://s2.wp.com/_static/??-eJyFkOsKwjAMhV/IWDbnD3+Iz7JLVlJ7s2kt+vRWNwV1KAQSku8cDhHZA9lepwFZqFKnhOEyt7XilfgFgCEZ2ohrQ/YJ985GtPHOGteRRkiMoZVlV4xGt8B5x9Egc4EWru+RyJ4J819MYfRtf4SATNcv1047CV4nSZZFmSUOLkUYndYui0yDxPipMemlmIDHO6YRumQ8zMEOZl81zaauq121VTdrXIQQ'></script>
<link rel='stylesheet' id='all-css-0' href='https://s2.wp.com/wp-content/mu-plugins/highlander-comments/style.css?m=1377793621g' type='text/css' media='all' />
<!--[if lt IE 8]>
<link rel='stylesheet' id='highlander-comments-ie7-css' href='https://s2.wp.com/wp-content/mu-plugins/highlander-comments/style-ie7.css?m=1351637563g&ver=20110606' type='text/css' media='all' />
<![endif]-->
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://marcmutz.wordpress.com/xmlrpc.php?rsd" />
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="https://s1.wp.com/wp-includes/wlwmanifest.xml" />
<meta name="generator" content="WordPress.com" />
<link rel="canonical" href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/" />
<link rel='shortlink' href='http://wp.me/P10053-3H' />
<link rel="alternate" type="application/json+oembed" href="https://public-api.wordpress.com/oembed/1.0/?format=json&url=https%3A%2F%2Fmarcmutz.wordpress.com%2Ftranslated-articles%2Fpimp-my-pimpl%2F&for=wpcom-auto-discovery" /><link rel="alternate" type="application/xml+oembed" href="https://public-api.wordpress.com/oembed/1.0/?format=xml&url=https%3A%2F%2Fmarcmutz.wordpress.com%2Ftranslated-articles%2Fpimp-my-pimpl%2F&for=wpcom-auto-discovery" />
<!-- Jetpack Open Graph Tags -->
<meta property="og:type" content="article" />
<meta property="og:title" content="Pimp My Pimpl" />
<meta property="og:url" content="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/" />
<meta property="og:description" content="This is a translation of a two-part article that originally appeared in Heise Developer. You can find the originals here: Part One: Part Two: You can find Part Two here: Pimp My Pimpl Much has been..." />
<meta property="article:published_time" content="2011-04-16T07:12:16+00:00" />
<meta property="article:modified_time" content="2011-08-26T15:56:34+00:00" />
<meta property="og:site_name" content="-Wmarc" />
<meta property="og:image" content="http://vg01.met.vgwort.de/na/c709de8282f542f88331fe738e99e6df" />
<meta property="og:locale" content="en_US" />
<meta name="twitter:site" content="@wordpressdotcom" />
<meta name="twitter:image" content="http://vg01.met.vgwort.de/na/c709de8282f542f88331fe738e99e6df?w=240" />
<meta name="twitter:card" content="summary" />
<meta property="fb:app_id" content="249643311490" />
<meta property="article:publisher" content="https://www.facebook.com/WordPresscom" />
<link rel="shortcut icon" type="image/x-icon" href="https://s2.wp.com/i/favicon.ico" sizes="16x16 24x24 32x32 48x48" />
<link rel="icon" type="image/x-icon" href="https://s2.wp.com/i/favicon.ico" sizes="16x16 24x24 32x32 48x48" />
<link rel="apple-touch-icon-precomposed" href="https://s0.wp.com/i/webclip.png" />
<link rel='openid.server' href='https://marcmutz.wordpress.com/?openidserver=1' />
<link rel='openid.delegate' href='https://marcmutz.wordpress.com/' />
<link rel="search" type="application/opensearchdescription+xml" href="https://marcmutz.wordpress.com/osd.xml" title="-Wmarc" />
<link rel="search" type="application/opensearchdescription+xml" href="https://wordpress.com/opensearch.xml" title="WordPress.com" />
<style>
@media screen and (min-width: 783px) {
#wpadminbar .quicklinks li#wp-admin-bar-my-account.with-avatar > a img {
margin-top: 5px;
}
}
</style>
<meta name="application-name" content="-Wmarc" /><meta name="msapplication-window" content="width=device-width;height=device-height" /><meta name="msapplication-tooltip" content="Marc Mutz on Qt, Boost, and C++" /><meta name="msapplication-task" content="name=Subscribe;action-uri=https://marcmutz.wordpress.com/feed/;icon-uri=https://s2.wp.com/i/favicon.ico" /><meta name="msapplication-task" content="name=Sign up for a free blog;action-uri=http://wordpress.com/signup/;icon-uri=https://s2.wp.com/i/favicon.ico" /><meta name="msapplication-task" content="name=WordPress.com Support;action-uri=http://support.wordpress.com/;icon-uri=https://s2.wp.com/i/favicon.ico" /><meta name="msapplication-task" content="name=WordPress.com Forums;action-uri=http://forums.wordpress.com/;icon-uri=https://s2.wp.com/i/favicon.ico" /><meta name="title" content="Pimp My Pimpl | -Wmarc on WordPress.com" />
<meta name="description" content="This is a translation of a two-part article that originally appeared in Heise Developer. You can find the originals here: Part One: http://www.heise.de/developer/artikel/C-Vor-und-Nachteile-des-d-Zeiger-Idioms-Teil-1-1097781.html Part Two: http://www.heise.de/developer/artikel/C-Vor-und-Nachteile-des-d-Zeiger-Idioms-Teil-2-1136104.html You can find Part Two here: https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl-—-reloaded/ Pimp My Pimpl Much has been written about this funnily-named idiom, alternatively known as d-pointer, compiler firewall, or Cheshire Cat. Heise Developer…" />
<style type="text/css">
#header {
background: transparent url(https://marcmutz.files.wordpress.com/2010/07/bird-feeding-gradient-3.jpg) no-repeat;
border: none;
}
</style>
<style type="text/css">
#header h1,
#header h1 a,
#header h1 a:visited,
#header h4,
#header h4 a,
#header h4 a:visited,
.header-left {
color: #000000;
}
</style>
<style type="text/css" id="syntaxhighlighteranchor"></style>
</head>
<body class="page page-id-229 page-child parent-pageid-227 page-template-default mp6 customizer-styles-applied highlander-enabled highlander-light">
<div id="header">
<div class="header-left">
<h4><a href="https://marcmutz.wordpress.com/">-Wmarc</a></h4>
<p id="description">Marc Mutz on Qt, Boost, and C++</p>
</div>
<div class="header-right">
<form method="get" id="searchform" action="https://marcmutz.wordpress.com/" >
<div><label class="hidden" for="s">Search:</label>
<input type="text" value="" name="s" id="s" />
<input type="submit" id="searchsubmit" value="Go" /></div>
</form>
</div>
</div>
<div id="access">
<div id="nav">
<div id="supernav" class="navleft nav">
<div class="menu"><ul><li ><a href="https://marcmutz.wordpress.com/">Home</a></li><li class="page_item page-item-2"><a href="https://marcmutz.wordpress.com/about/">About</a></li><li class="page_item page-item-23 page_item_has_children"><a href="https://marcmutz.wordpress.com/effective-qt/">Effective Qt</a><ul class='children'><li class="page_item page-item-26"><a href="https://marcmutz.wordpress.com/effective-qt/subclassing/">Don’t be sub-class when subclassing</a></li><li class="page_item page-item-543"><a href="https://marcmutz.wordpress.com/effective-qt/strings/">Four Strings to a Bow</a></li><li class="page_item page-item-256"><a href="https://marcmutz.wordpress.com/effective-qt/prefer-to-use-normalised-signalslot-signatures/">Prefer to use normalised signal/slot signatures</a></li><li class="page_item page-item-135"><a href="https://marcmutz.wordpress.com/effective-qt/containers/">Understand the Qt containers</a></li><li class="page_item page-item-29"><a href="https://marcmutz.wordpress.com/effective-qt/casting/">Coming Soon: Prefer qobject_cast() over isA()/inherits()</a></li><li class="page_item page-item-53"><a href="https://marcmutz.wordpress.com/effective-qt/properties/">Coming Soon: Property properly</a></li><li class="page_item page-item-54"><a href="https://marcmutz.wordpress.com/effective-qt/moc/">Coming Soon: Mocking moc</a></li></ul></li><li class="page_item page-item-471 page_item_has_children"><a href="https://marcmutz.wordpress.com/private-practice/">Private Practice</a><ul class='children'><li class="page_item page-item-474"><a href="https://marcmutz.wordpress.com/private-practice/private-practice-taming-templates/">Private Practice: Taming Templates</a></li><li class="page_item page-item-497"><a href="https://marcmutz.wordpress.com/private-practice/whats-in-a-proxy-style/">What’s in a Proxy-Style?</a></li></ul></li><li class="page_item page-item-227 page_item_has_children current_page_ancestor current_page_parent"><a href="https://marcmutz.wordpress.com/translated-articles/">Translated Articles</a><ul class='children'><li class="page_item page-item-229 current_page_item"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/">Pimp My Pimpl</a></li><li class="page_item page-item-306"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl-%e2%80%94-reloaded/">Pimp My Pimpl — Reloaded</a></li></ul></li></ul></div>
</div>
<div class="navright">
<a class="rsslink" rel="nofollow" href="https://marcmutz.wordpress.com/feed/">Posts</a>
<a class="rsslink" rel="nofollow" href="https://marcmutz.wordpress.com/comments/feed/">Comments</a>
</div>
</div>
<div id="subnav" class="subnav nav">
<div class="menu">
<ul>
<li class="cat-item cat-item-3205"><a href="https://marcmutz.wordpress.com/category/english/" >English</a>
</li>
<li class="cat-item cat-item-2765"><a href="https://marcmutz.wordpress.com/category/german/" >German</a>
</li>
<li class="cat-item cat-item-2426"><a href="https://marcmutz.wordpress.com/category/programming-languages/c/" >C++</a>
</li>
<li class="cat-item cat-item-61037"><a href="https://marcmutz.wordpress.com/category/software-libraries/qt/" >Qt</a>
</li>
<li class="cat-item cat-item-214632"><a href="https://marcmutz.wordpress.com/category/software-libraries/boost/" >Boost</a>
</li>
<li class="cat-item cat-item-1068504"><a href="https://marcmutz.wordpress.com/category/programming-languages/c/c0x/" >C++0x</a>
</li>
<li class="cat-item cat-item-39389780"><a href="https://marcmutz.wordpress.com/category/columns/heise-developer/" >Heise Developer</a>
</li>
<li class="cat-item cat-item-39438656"><a href="https://marcmutz.wordpress.com/category/columns/effective-qt/" >Effective Qt</a>
</li>
<li class="cat-item cat-item-990667"><a href="https://marcmutz.wordpress.com/category/columns/private-practice/" >Private Practice</a>
</li>
<li class="cat-item cat-item-2227387"><a href="https://marcmutz.wordpress.com/category/projects/gpg4win/" >Gpg4win</a>
</li>
</ul>
</div>
</div>
</div>
<div id="wrap">
<div id="content">
<div id="content-left">
<div class="post-229 page type-page status-publish hentry">
<div class="entry">
<h1>Pimp My Pimpl</h1>
<p><img src="http://vg01.met.vgwort.de/na/c709de8282f542f88331fe738e99e6df" width="1" height="1" alt=""><br />
This is a translation of a two-part article that originally appeared in <a href="http://www.heise.de/developer">Heise Developer</a>. You can find the originals here:</p>
<ul>
<li>Part One: <a href="http://www.heise.de/developer/artikel/C-Vor-und-Nachteile-des-d-Zeiger-Idioms-Teil-1-1097781.html">http://www.heise.de/developer/artikel/C-Vor-und-Nachteile-des-d-Zeiger-Idioms-Teil-1-1097781.html</a></li>
<li>Part Two: <a href="http://www.heise.de/developer/artikel/C-Vor-und-Nachteile-des-d-Zeiger-Idioms-Teil-2-1136104.html">http://www.heise.de/developer/artikel/C-Vor-und-Nachteile-des-d-Zeiger-Idioms-Teil-2-1136104.html</a></li>
</ul>
<p>You can find Part Two here:</p>
<ul>
<li><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl-%e2%80%94-reloaded/" title="Pimp My Pimpl — Reloaded">https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl-—-reloaded/</a></li>
</ul>
<h1>Pimp My Pimpl</h1>
<p><strong>Much has been written about this funnily-named idiom, alternatively known as d-pointer, compiler firewall, or Cheshire Cat. <em>Heise Developer</em> highlights some angles of this practical construct that go beyond the classic technique.</strong> <span id="more-229"></span></p>
<h2>Part One</h2>
<p>This article first recapitulates the classic Pimpl idiom (pointer-to-implementation), points out its advantages, and goes on to develop further idioms on its basis. The second part will concentrate on how to mitigate the disadvantages that inevitably arise through Pimpl use.</p>
<h3>The Classic Idiom</h3>
<p>Every C++ programmer has probably stumbled across a class definition akin to the following:</p>
<pre class="brush: cpp; title: ; notranslate" title="">
class Class {
// ...
private:
class Private; // forward declaration
Private * d; // hide impl details
};
</pre>
<p>Here, the programmer moved the data fields of his class <code>Class</code> into a nested class <code>Class::Private</code>. Instances of <code>Class</code> merely contain a pointer <code>d</code> to their <code>Class::Private</code> instance.</p>
<p>To understand why the class author used this indirection, we need to take a step back and look at the C++ module system. In contrast to many other languages, C++, as a language of C descent, has no built-in support for modules (such support was proposed for C++0x, but did not make it into the final standard). Instead, one factors module function declarations (but not usually their definitions) into header files, and makes them available to other modules using the <code>#include</code> preprocessor directive. This, however, leaves the header files filling a double role: On the one hand, they serve as the module interface. On the other, as a declaration site for potentially internal implementation details.</p>
<p>In times of C, this worked well: Implementation details of functions are encapsulated perfectly by the declaration/definition split; one could either merely <em>forward-declare</em> <code>struct</code>s (in which case they were private), or define them directly in the header file (in which case they were public). In “object-oriented C”, class <code>Class</code> from above would maybe look like the following:</p>
<pre class="brush: cpp; title: ; notranslate" title="">
struct Class; // forward declaration
typedef struct Class * Class_t; // -> only private members
void Class_new( Class_t * cls ); // Class::Class()
void Class_release( Class_t cls ); // Class::~Class()
int Class_f( Class_t cls, double num ); // int Class::f( double )
//...
</pre>
<p>Unfortunately, that doesn’t work in C++. Methods must be declared inside the class. Since classes without methods are rather boring, class definitions usually appear in C++ header files. Since classes, unlike namespaces, cannot be reopened, the header file must contain declarations for all (data fields, as well as) methods:</p>
<pre class="brush: cpp; title: ; notranslate" title="">
class Class {
public:
// ... public methods ... ok
private:
// ... private data & methods ... don't want these here
};
</pre>
<p>The problem is evident: The module interface (header file) necessarily contains implementation details; always a bad idea. That is why one uses a rather ugly trick and in short factors all implementation details (data fields as well as private methods) into a separate class:</p>
<pre class="brush: cpp; title: ; notranslate" title="">
// --- class.h ---
class Class {
public:
Class();
~Class();
// ... public methods ...
void f( double n );
private:
class Private;
Private * d;
};
// -- class.cpp --
#include <class.h>
class Class::Private {
public:
// ... private data & methods ...
bool canAcceptN( double num ) const { return num != 0 ; }
double n;
};
Class::Class()
: d( new Private ) {}
Class::~Class() {
delete d;
}
void Class::f( double n ) {
if ( d->canAcceptN( n ) )
d->n = n;
}
</pre>
<p>Since <code>Class::Private</code> is used only in the declaration of a pointer variable, ie. “in name only” (Lakos) and not “in size”, a forward declaration suffices, as in the C case. All methods of <code>Class</code> now access private methods and data members of <code>Class::Private</code> through <code>d</code> only.</p>
<p>In this way, one gains the convenience of a fully-encapsulating module system in C++, too. Because of the recourse to indirection, the developer pays for these benefits with an additional memory allocation (<code>new Class::Private</code>), the indirection on accessing data fields and private methods, as well as the total waiving of (at least public) <code>inline</code> methods. As the second part will show, the semantics of <code>const</code> methods also change.</p>
<p>Before the second part of this article addresses the issue of how to rectify, or at least mitigate, the above downsides, the remainder of this article will first shed some light on the idiom’s benefits.</p>
<h3>Benefits of the Pimpl Idiom</h3>
<p>They are substantial. By encapsulating all implementation details, a slim and long-term stable interface (header file) arises. The former leads to more readable class definitions; the latter helps maintaining binary compatibility even through extensive changes to the implementation.</p>
<p>For instance, Nokia’s “Qt Development Frameworks” department (formerly Trolltech) has carried out profound changes to the widget rendering at least twice during the development of their “Qt 4” class library without the need to so much as relink programs using Qt 4.</p>
<p>Particularly in larger projects, the tendency of the Pimpl Idiom to dramatically speed up builds should not be underestimated. This is accomplished both by a reduction of <code>#include</code> directives in header files and though the considerably reduced frequency of changes to header files of Pimpl classes in general. In “Exceptional C++”, Herb Sutter reports regular doubling of compilation speeds, John Lakos even claims build speed-ups of two orders of magnitude.</p>
<p>Another virtue of the design: classes with d-pointers are well-suited for transaction-oriented and exception-safe code, respectively. For instance, the developer may use the Copy-Swap Idiom (Sutter/Alexandrescu: C++ Coding Standards, Item 56) to create a transactional (all-or-nothing) copy assignment operator:</p>
<pre class="brush: cpp; title: ; notranslate" title="">
class Class {
// ...
void swap( Class & other ) {
std::swap( d, other.d );
}
Class & operator=( const Class & other ) {
// this may fail, but doesn't change *this
Class copy( other );
// this cannot fail, commits to *this:
swap( copy );
return *this;
}
</pre>
<p>Implementation of <a href="http://en.wikipedia.org/wiki/C++0x#Rvalue_reference_and_move_semantics">C++0x move operations</a> is trivial as well (and, in particular, identical across all Pimpl classes):</p>
<pre class="brush: cpp; title: ; notranslate" title="">
// C++0x move semantics:
Class( Class && other ) : d( other.d ) { other.d = 0; }
Class & operator=( Class && other ) {
std::swap( d, other.d );
return *this;
}
// ...
};
</pre>
<p>Both member swap and assignment operators may be implemented <code>inline</code> in this model, without compromising the class’ encapsulation; developers should make good use of this fact.</p>
<h3>Extended Means of Composition</h3>
<p>As the last benefit the option to cut down on some of the extra dynamic memory allocations through direct aggregation of data fields should be mentioned. Without Pimpl, aggregation would customarily have been through a pointer in order to decouple classes from each other (a kind of Pimpl per data field). By “pimpling” the whole class once, the need to hold private data fields of complex type only though pointers can be dispensed with.</p>
<p>For instance, the idiomatic Qt dialog class</p>
<pre class="brush: cpp; title: ; notranslate" title="">
class QLineEdit;
class QLabel;
class MyDialog : public QDialog {
// ...
private:
// idiomatic Qt:
QLabel * m_loginLB;
QLineEdit * m_loginLE;
QLabel * m_passwdLB;
QLineEdit * m_passwdLE;
};
</pre>
<p>turns into</p>
<pre class="brush: cpp; title: ; notranslate" title="">
#include <QLabel>
#include <QLineEdit>
class MyDialog::Private {
// ...
// not idiomatic Qt, but less heap allocations:
QLabel loginLB;
QLineEdit loginLE;
QLabel passwdLB;
QLineEdit passwdLE;
};
</pre>
<p>Qt aficionados may argue that the <code>QDialog</code> destructor already destroys the child widgets; direct aggregation would therefore trigger a double-delete. Indeed, usage of this technique poses the threat of allocation sequence errors (double-delete, use-after-free, etc), particularly if data fields are also owned by the class, and vice versa. The transformation shown, however, is safe here, since Qt always allows to delete children before their parents.</p>
<p>This approach is especially effective in case data fields aggregated this way are themselves instances of “pimpled” classes. This is the case in the example shown, and usage of the Pimpl Idiom saves four dynamic memory allocations of size <code>sizeof(void*)</code> while incurring only one additional (larger) allocation. This can lead to more efficient use of the heap, since small allocations regularly create especially high overhead in the allocator.</p>
<p>In addition, the compiler is much more likely to “de-virtualise” calls to virtual functions in this scenario, ie. it removes the double indirection caused by the virtuality of the function call. This requires interprocedural optimisation when using aggregation by pointer. Whether or not this indeed constitutes a win in runtime performance against the background of an extra indirection though the d-pointer has to be checked as needed by profiling concrete classes.</p>
<p>In case profiling shows that the dynamic memory allocation turns in to a bottleneck, the “Fast Pimpl” Idiom (Exceptional C++, Item 30) may produce relief. In this variant, a fast allocator, e.g. <a href="http://www.boost.org/doc/libs/release/libs/pool/doc/interfaces/singleton_pool.html"><code>boost::singleton_pool</code></a>, is used to create <code>Private</code> instances instead of global <code>operator new()</code>.</p>
<h3>Interim Findings</h3>
<p>As a well-known C++ idiom, Pimpl allows class authors to separate class interface and implementation to an extent not directly provided for by C++. As a positive side-effect, the use of d-pointers speeds up compilation runs, eases implementation of transaction semantics, and allows, through extended means of composition, implementations that potentially are more runtime-efficient.</p>
<p>Not everything is shiny when using d-pointers, though: In addition to the extra <code>Private</code> class, and its dynamic memory allocation, modified <code>const</code> method semantics, as well as potential allocation sequence errors are cause for concern.</p>
<p>For some of these, the author will show solutions in the second part of the article. Complexity will increase further, though, so that for each concrete case one has to verify anew that the benefits of the idiom outweigh the downsides. If in doubt, this needs to be done per class in question. As usual, there can be no blanket judgements.</p>
<h3>Outlook</h3>
<p>The <a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl-%e2%80%94-reloaded/" title="Pimp My Pimpl — Reloaded">second and last part of this article</a> will take a closer look under the hood of Pimpl, uncover the rust-streaked areas, and pimp the idiom using a whole array of accessories.</p>
<div id="jp-post-flair" class="sharedaddy sd-rating-enabled sd-like-enabled sd-sharing-enabled"><div class="sd-block sd-rating"><h3 class="sd-title">Rate this:</h3><div class="pd-rating" id="pd_rating_holder_2480796_page_229"></div></div><div class="sharedaddy sd-sharing-enabled"><div class="robots-nocontent sd-block sd-social sd-social-icon-text sd-sharing"><h3 class="sd-title">Share this:</h3><div class="sd-content"><ul><li class="share-twitter"><a rel="nofollow" data-shared="sharing-twitter-229" class="share-twitter sd-button share-icon" href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?share=twitter" target="_blank" title="Click to share on Twitter"><span>Twitter</span></a></li><li class="share-reddit"><a rel="nofollow" data-shared="" class="share-reddit sd-button share-icon" href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?share=reddit" target="_blank" title="Click to share on Reddit"><span>Reddit</span></a></li><li class="share-google-plus-1"><a rel="nofollow" data-shared="sharing-google-229" class="share-google-plus-1 sd-button share-icon" href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?share=google-plus-1" target="_blank" title="Click to share on Google+"><span>Google</span></a></li><li class="share-email"><a rel="nofollow" data-shared="" class="share-email sd-button share-icon" href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?share=email" target="_blank" title="Click to email"><span>Email</span></a></li><li class="share-print"><a rel="nofollow" data-shared="" class="share-print sd-button share-icon" href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/#print" target="_blank" title="Click to print"><span>Print</span></a></li><li class="share-end"></li></ul></div></div></div><div class='sharedaddy sd-block sd-like jetpack-likes-widget-wrapper jetpack-likes-widget-unloaded' id='like-post-wrapper-14776649-229-5686526946e7e' data-src='//widgets.wp.com/likes/#blog_id=14776649&post_id=229&origin=marcmutz.wordpress.com&obj_id=14776649-229-5686526946e7e' data-name='like-post-frame-14776649-229-5686526946e7e'><h3 class='sd-title'>Like this:</h3><div class='likes-widget-placeholder post-likes-widget-placeholder' style='height:55px'><span class='button'><span>Like</span></span> <span class="loading">Loading...</span></div><span class='sd-text-color'></span><a class='sd-link-color'></a></div></div><div class="clear"></div>
<div class="clear"></div>
</div>
</div>
<div id="comments">
<div id="comments">
<h3 id="comments-title">13 Responses to <em>Pimp My Pimpl</em> </h3>
<ol class="commentlist snap_preview">
<li class="post pingback">
<p>Pingback: <a href='https://marcmutz.wordpress.com/2011/04/16/translated-pimp-my-pimpl-part-1/' rel='external nofollow' class='url'>Translated: Pimp My Pimpl (part 1) « -Wmarc</a></p>
</li><!-- #comment-## -->
<li class="post pingback">
<p>Pingback: <a href='https://marcmutz.wordpress.com/2010/10/05/heise-developer-pimp-my-pimpl-part-1/' rel='external nofollow' class='url'>Heise Developer: Pimp My Pimpl (part 1) « -Wmarc</a></p>
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1 highlander-comment" id="li-comment-174">
<div id="comment-174">
<div class="comment-author vcard">
<img alt='' src='https://2.gravatar.com/avatar/b2feaf669090ecd1eba6049704bcc610?s=40&d=identicon&r=G' class='avatar avatar-40' height='40' width='40' /> <cite class="fn">Joe</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/#comment-174">2011-04-16 at 13:33</a></div>
<div class="comment-body"><p>Good job! Awesome article!</p>
<p>I found typo:<br />
void Class_new( Class_t * cls ); // Class::Class()<br />
probably must be:<br />
void Class_new( Class_t cls ); // Class::Class()<br />
because Class_t is already pointer.<br />
It’s not your typo, just retyped from original.</p>
<p>P.S. Think I make translation of this article into russian, so it will be amazing to have part 2 in English as I don’t know Deutsch.</p>
</div>
<div class="reply">
<a rel='nofollow' class='comment-reply-link' href='https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?replytocom=174#respond' onclick='return addComment.moveForm( "comment-174", "174", "respond", "229" )' aria-label='Reply to Joe'>Reply</a> </div>
</div>
<ul class="children">
<li class="comment byuser comment-author-marcmutz comment-author-is-site-member bypostauthor odd alt depth-2 highlander-comment" id="li-comment-175">
<div id="comment-175">
<div class="comment-author vcard">
<img alt='' src='https://2.gravatar.com/avatar/51b7f05de9889e7212f949f0fd975922?s=40&d=identicon&r=G' class='avatar avatar-40' height='40' width='40' /> <cite class="fn"><a href='https://marcmutz.wordpress.com' rel='external nofollow' class='url'>marcmutz</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/#comment-175">2011-04-16 at 13:40</a></div>
<div class="comment-body"><p>No, the code is correct as it is. It needs to be a pointer-to-<code>Class_t</code>, so the “constructor” can assign to it:</p>
<pre class="brush: cpp; title: ; notranslate" title="">
Class_t c = 0;
Class_new( &c );
// now c != 0 (hopefully)
// ...
Class_release( c );
c = 0;
</pre>
<p>Alternatively, <code>Class_new()</code> could return the new pointer, but C class libraries usually reserve the return value for error codes.</p>
</div>
<div class="reply">
<a rel='nofollow' class='comment-reply-link' href='https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?replytocom=175#respond' onclick='return addComment.moveForm( "comment-175", "175", "respond", "229" )' aria-label='Reply to marcmutz'>Reply</a> </div>
</div>
<ul class="children">
<li class="comment even depth-3 highlander-comment" id="li-comment-178">
<div id="comment-178">
<div class="comment-author vcard">
<img alt='' src='https://2.gravatar.com/avatar/b2feaf669090ecd1eba6049704bcc610?s=40&d=identicon&r=G' class='avatar avatar-40' height='40' width='40' /> <cite class="fn">Joe</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/#comment-178">2011-04-16 at 17:39</a></div>
<div class="comment-body"><p>You are right</p>
</div>
<div class="reply">
<a rel='nofollow' class='comment-reply-link' href='https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?replytocom=178#respond' onclick='return addComment.moveForm( "comment-178", "178", "respond", "229" )' aria-label='Reply to Joe'>Reply</a> </div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment byuser comment-author-marcmutz comment-author-is-site-member bypostauthor odd alt depth-2 highlander-comment" id="li-comment-176">
<div id="comment-176">
<div class="comment-author vcard">
<img alt='' src='https://2.gravatar.com/avatar/51b7f05de9889e7212f949f0fd975922?s=40&d=identicon&r=G' class='avatar avatar-40' height='40' width='40' /> <cite class="fn"><a href='https://marcmutz.wordpress.com' rel='external nofollow' class='url'>marcmutz</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/#comment-176">2011-04-16 at 13:44</a></div>
<div class="comment-body"><p>> P.S. Think I make translation of this article into russian, so it will be amazing to have part 2 in English as I don’t know Deutsch.</p>
<p>Be my guest. The only requirement I have is that you link back to both the German (on heise.de) and English versions (this one), and let me link to your Russian one from here.<br />
Yes, I intend to translate the second part, too, at some point.</p>
</div>
<div class="reply">
<a rel='nofollow' class='comment-reply-link' href='https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?replytocom=176#respond' onclick='return addComment.moveForm( "comment-176", "176", "respond", "229" )' aria-label='Reply to marcmutz'>Reply</a> </div>
</div>
<ul class="children">
<li class="comment even depth-3 highlander-comment" id="li-comment-177">
<div id="comment-177">
<div class="comment-author vcard">
<img alt='' src='https://2.gravatar.com/avatar/b2feaf669090ecd1eba6049704bcc610?s=40&d=identicon&r=G' class='avatar avatar-40' height='40' width='40' /> <cite class="fn">Joe</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/#comment-177">2011-04-16 at 16:49</a></div>
<div class="comment-body"><p>Ok, I will make it so</p>
</div>
<div class="reply">
<a rel='nofollow' class='comment-reply-link' href='https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?replytocom=177#respond' onclick='return addComment.moveForm( "comment-177", "177", "respond", "229" )' aria-label='Reply to Joe'>Reply</a> </div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment odd alt thread-odd thread-alt depth-1 highlander-comment" id="li-comment-179">
<div id="comment-179">
<div class="comment-author vcard">
<img alt='' src='https://2.gravatar.com/avatar/b2feaf669090ecd1eba6049704bcc610?s=40&d=identicon&r=G' class='avatar avatar-40' height='40' width='40' /> <cite class="fn">Joe</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/#comment-179">2011-04-16 at 20:46</a></div>
<div class="comment-body"><p>>typedef Class * Class_t;</p>
<p>I guess it should be:<br />
typedef struct Class * Class_t;</p>
</div>
<div class="reply">
<a rel='nofollow' class='comment-reply-link' href='https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?replytocom=179#respond' onclick='return addComment.moveForm( "comment-179", "179", "respond", "229" )' aria-label='Reply to Joe'>Reply</a> </div>
</div>
<ul class="children">
<li class="comment byuser comment-author-marcmutz comment-author-is-site-member bypostauthor even depth-2 highlander-comment" id="li-comment-180">
<div id="comment-180">
<div class="comment-author vcard">
<img alt='' src='https://2.gravatar.com/avatar/51b7f05de9889e7212f949f0fd975922?s=40&d=identicon&r=G' class='avatar avatar-40' height='40' width='40' /> <cite class="fn"><a href='https://marcmutz.wordpress.com' rel='external nofollow' class='url'>marcmutz</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/#comment-180">2011-04-16 at 21:12</a></div>
<div class="comment-body"><p>Fixed, thanks!</p>
</div>
<div class="reply">
<a rel='nofollow' class='comment-reply-link' href='https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?replytocom=180#respond' onclick='return addComment.moveForm( "comment-180", "180", "respond", "229" )' aria-label='Reply to marcmutz'>Reply</a> </div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment odd alt thread-even depth-1 highlander-comment" id="li-comment-182">
<div id="comment-182">
<div class="comment-author vcard">
<img alt='' src='https://2.gravatar.com/avatar/b2feaf669090ecd1eba6049704bcc610?s=40&d=identicon&r=G' class='avatar avatar-40' height='40' width='40' /> <cite class="fn">Joe</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/#comment-182">2011-04-17 at 20:06</a></div>
<div class="comment-body"><p>I suggest to turn code</p>
<p><code><br />
#include<br />
#include </p>
<p>class MyDialog::Private {<br />
// ...<br />
// not idiomatic Qt, but less heap allocations:<br />
QLabel loginLB;<br />
QLineEdit loginLE;<br />
QLabel passwdLB;<br />
QLineEdit passwdLE;<br />
};<br />
</code></p>
<p>to this one:</p>
<p><code><br />
#include<br />
#include </p>
<p>class MyDialog::Private {<br />
// ...<br />
public:<br />
// not idiomatic Qt, but less heap allocations:<br />
QLabel loginLB;<br />
QLineEdit loginLE;<br />
QLabel passwdLB;<br />
QLineEdit passwdLE;<br />
};<br />
</code></p>
<p>to explicitly show that data fields locates at public section</p>
</div>
<div class="reply">
<a rel='nofollow' class='comment-reply-link' href='https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?replytocom=182#respond' onclick='return addComment.moveForm( "comment-182", "182", "respond", "229" )' aria-label='Reply to Joe'>Reply</a> </div>
</div>
<ul class="children">
<li class="comment byuser comment-author-marcmutz comment-author-is-site-member bypostauthor even depth-2 highlander-comment" id="li-comment-184">
<div id="comment-184">
<div class="comment-author vcard">
<img alt='' src='https://2.gravatar.com/avatar/51b7f05de9889e7212f949f0fd975922?s=40&d=identicon&r=G' class='avatar avatar-40' height='40' width='40' /> <cite class="fn"><a href='https://marcmutz.wordpress.com' rel='external nofollow' class='url'>marcmutz</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/#comment-184">2011-04-18 at 14:45</a></div>
<div class="comment-body"><p>> to explicitly show that data fields locates at public section</p>
<p>I don’t think they should be public. Esp. if you do the Qt-style <code>DerivedPrivate : public BasePrivate</code> from part II, you don’t want all data members to be at most protected. Just make <code>Class::Private</code> a friend of <code>Class</code>.</p>
</div>
<div class="reply">
<a rel='nofollow' class='comment-reply-link' href='https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?replytocom=184#respond' onclick='return addComment.moveForm( "comment-184", "184", "respond", "229" )' aria-label='Reply to marcmutz'>Reply</a> </div>
</div>
</li><!-- #comment-## -->
</ul><!-- .children -->
</li><!-- #comment-## -->
<li class="comment odd alt thread-odd thread-alt depth-1 highlander-comment" id="li-comment-183">
<div id="comment-183">
<div class="comment-author vcard">
<img alt='' src='https://0.gravatar.com/avatar/0ba3dff2713f82030e7f0fcbd719325a?s=40&d=identicon&r=G' class='avatar avatar-40' height='40' width='40' /> <cite class="fn"><a href='http://Www.kjellkod.cc' rel='external nofollow' class='url'>Kjell Hedstrom</a></cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/#comment-183">2011-04-17 at 20:21</a></div>
<div class="comment-body"><p>Great part one. Can’t wait for part two, in English. In my opinion d-ptr a.k.a Pimpl is not nearly used enough.</p>
<p>Another area when I’ve used this technique is when using actors (or active objects) to make it explicitly clear what belongs to the API for “users” and what are worker thread internals…</p>
</div>
<div class="reply">
<a rel='nofollow' class='comment-reply-link' href='https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?replytocom=183#respond' onclick='return addComment.moveForm( "comment-183", "183", "respond", "229" )' aria-label='Reply to Kjell Hedstrom'>Reply</a> </div>
</div>
</li><!-- #comment-## -->
<li class="comment even thread-even depth-1 highlander-comment" id="li-comment-186">
<div id="comment-186">
<div class="comment-author vcard">
<img alt='' src='https://2.gravatar.com/avatar/b2feaf669090ecd1eba6049704bcc610?s=40&d=identicon&r=G' class='avatar avatar-40' height='40' width='40' /> <cite class="fn">Joe</cite> <span class="says">says:</span> </div>
<div class="comment-meta commentmetadata"><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/#comment-186">2011-04-23 at 00:19</a></div>
<div class="comment-body"><p>There is link to my translation: <a href="http://habrahabr.ru/blogs/cpp/118010/" rel="nofollow">http://habrahabr.ru/blogs/cpp/118010/</a><br />
It contains link to original (deutsch) article and your translation, as I promised.</p>
</div>
<div class="reply">
<a rel='nofollow' class='comment-reply-link' href='https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/?replytocom=186#respond' onclick='return addComment.moveForm( "comment-186", "186", "respond", "229" )' aria-label='Reply to Joe'>Reply</a> </div>
</div>
</li><!-- #comment-## -->
</ol>
<div id="respond" class="comment-respond">
<h3 id="reply-title" class="comment-reply-title">Leave a Reply <small><a rel="nofollow" id="cancel-comment-reply-link" href="/translated-articles/pimp-my-pimpl/#respond" style="display:none;">Cancel reply</a></small></h3> <form action="https://marcmutz.wordpress.com/wp-comments-post.php" method="post" id="commentform" class="comment-form">
<input type="hidden" id="highlander_comment_nonce" name="highlander_comment_nonce" value="0a99737c2d" /><input type="hidden" name="_wp_http_referer" value="/translated-articles/pimp-my-pimpl/" />
<input type="hidden" name="hc_post_as" id="hc_post_as" value="guest" />
<div class="comment-form-field comment-textarea">
<label for="comment">Enter your comment here...</label>
<div id="comment-form-comment"><textarea id="comment" name="comment" title="Enter your comment here..."></textarea></div>
</div>
<div id="comment-form-identity">
<div id="comment-form-nascar">
<p>Fill in your details below or click an icon to log in:</p>
<ul>
<li class="selected" style="display:none;">
<a href="#comment-form-guest" id="postas-guest" title="Guest">
<span></span>
</a>
</li>
<li>
<a href="#comment-form-load-service:WordPress.com" id="postas-wordpress" title="WordPress.com">
<span></span>
</a>
</li>
<li>
<a href="#comment-form-load-service:Twitter" id="postas-twitter" title="Twitter">
<span></span>
</a>
</li>
<li>
<a href="#comment-form-load-service:Facebook" id="postas-facebook" title="Facebook">
<span></span>
</a>
</li>
<li>
<iframe id="googleplus-sign-in" name="googleplus-sign-in" src="https://public-api.wordpress.com/connect/?googleplus-sign-in=https%3A%2F%2Fmarcmutz.wordpress.com" width="24" height="24" scrolling="no" allowtransparency="true" seamless="seamless" frameborder="0"></iframe>
</li>
</ul>
</div>
<div id="comment-form-guest" class="comment-form-service selected">
<div class="comment-form-padder">
<div class="comment-form-avatar">
<a href="https://gravatar.com/site/signup/" target="_blank"> <img src="https://1.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=25&d=identicon&forcedefault=y&r=G" alt="Gravatar" width="25" class="no-grav" />
</a> </div>
<div class="comment-form-fields">
<div class="comment-form-field comment-form-email">
<label for="email">Email <span class="required">(required)</span> <span class="nopublish">(Address never made public)</span></label>
<div class="comment-form-input"><input id="email" name="email" type="email" value="" /></div>
</div>
<div class="comment-form-field comment-form-author">
<label for="author">Name <span class="required">(required)</span></label>
<div class="comment-form-input"><input id="author" name="author" type="text" value="" /></div>
</div>
<div class="comment-form-field comment-form-url">
<label for="url">Website</label>
<div class="comment-form-input"><input id="url" name="url" type="text" value="" /></div>
</div>
</div>
</div>
</div>
<div id="comment-form-wordpress" class="comment-form-service">
<div class="comment-form-padder">
<div class="comment-form-avatar">
<img src="https://s2.wp.com/wp-content/mu-plugins/highlander-comments/images/wplogo.png" alt="WordPress.com Logo" width="25" class="no-grav" />
</div>
<div class="comment-form-fields">
<input type="hidden" name="wp_avatar" id="wordpress-avatar" class="comment-meta-wordpress" value="" />
<input type="hidden" name="wp_user_id" id="wordpress-user_id" class="comment-meta-wordpress" value="" />
<input type="hidden" name="wp_access_token" id="wordpress-access_token" class="comment-meta-wordpress" value="" />
<p class="comment-form-posting-as pa-wordpress"><strong></strong> You are commenting using your WordPress.com account. <span class="comment-form-log-out">( <a href="javascript:HighlanderComments.doExternalLogout( 'wordpress' );">Log Out</a> / <a href="#" onclick="javascript:HighlanderComments.switchAccount();return false;">Change</a> )</span></p>
</div>
</div>
</div>
<div id="comment-form-twitter" class="comment-form-service">
<div class="comment-form-padder">
<div class="comment-form-avatar">
<img src="https://1.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=25&d=identicon&forcedefault=y&r=G" alt="Twitter picture" width="25" class="no-grav" />
</div>
<div class="comment-form-fields">
<input type="hidden" name="twitter_avatar" id="twitter-avatar" class="comment-meta-twitter" value="" />
<input type="hidden" name="twitter_user_id" id="twitter-user_id" class="comment-meta-twitter" value="" />
<input type="hidden" name="twitter_access_token" id="twitter-access_token" class="comment-meta-twitter" value="" />
<p class="comment-form-posting-as pa-twitter"><strong></strong> You are commenting using your Twitter account. <span class="comment-form-log-out">( <a href="javascript:HighlanderComments.doExternalLogout( 'twitter' );">Log Out</a> / <a href="#" onclick="javascript:HighlanderComments.switchAccount();return false;">Change</a> )</span></p>
</div>
</div>
</div>
<div id="comment-form-facebook" class="comment-form-service">
<div class="comment-form-padder">
<div class="comment-form-avatar">
<img src="https://1.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=25&d=identicon&forcedefault=y&r=G" alt="Facebook photo" width="25" class="no-grav" />
</div>
<div class="comment-form-fields">
<input type="hidden" name="fb_avatar" id="facebook-avatar" class="comment-meta-facebook" value="" />
<input type="hidden" name="fb_user_id" id="facebook-user_id" class="comment-meta-facebook" value="" />
<input type="hidden" name="fb_access_token" id="facebook-access_token" class="comment-meta-facebook" value="" />
<p class="comment-form-posting-as pa-facebook"><strong></strong> You are commenting using your Facebook account. <span class="comment-form-log-out">( <a href="javascript:HighlanderComments.doExternalLogout( 'facebook' );">Log Out</a> / <a href="#" onclick="javascript:HighlanderComments.switchAccount();return false;">Change</a> )</span></p>
</div>
</div>
</div>
<div id="comment-form-googleplus" class="comment-form-service">
<div class="comment-form-padder">
<div class="comment-form-avatar">
<img src="https://1.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536?s=25&d=identicon&forcedefault=y&r=G" alt="Google+ photo" width="25" class="no-grav" />
</div>
<div class="comment-form-fields">
<input type="hidden" name="googleplus_avatar" id="googleplus-avatar" class="comment-meta-googleplus" value="" />
<input type="hidden" name="googleplus_user_id" id="googleplus-user_id" class="comment-meta-googleplus" value="" />
<input type="hidden" name="googleplus_access_token" id="googleplus-access_token" class="comment-meta-googleplus" value="" />
<p class="comment-form-posting-as pa-googleplus"><strong></strong> You are commenting using your Google+ account. <span class="comment-form-log-out">( <a href="javascript:HighlanderComments.doExternalLogout( 'googleplus' );">Log Out</a> / <a href="#" onclick="javascript:HighlanderComments.switchAccount();return false;">Change</a> )</span></p>
</div>
</div>
</div>
<div id="comment-form-load-service" class="comment-form-service">
<div class="comment-form-posting-as-cancel"><a href="javascript:HighlanderComments.cancelExternalWindow();">Cancel</a></div>
<p>Connecting to %s</p>
</div>
</div>
<script type="text/javascript">
var highlander_expando_javascript = function(){
var input = document.createElement( 'input' ),
comment = jQuery( '#comment' );
if ( 'placeholder' in input ) {
comment.attr( 'placeholder', jQuery( '.comment-textarea label' ).remove().text() );
}
// Expando Mode: start small, then auto-resize on first click + text length
jQuery( '#comment-form-identity' ).hide();
jQuery( '#comment-form-subscribe' ).hide();
jQuery( '#commentform .form-submit' ).hide();
comment.css( { 'height':'10px' } ).one( 'focus', function() {
var timer = setInterval( HighlanderComments.resizeCallback, 10 )
jQuery( this ).animate( { 'height': HighlanderComments.initialHeight } ).delay( 100 ).queue( function(n) { clearInterval( timer ); HighlanderComments.resizeCallback(); n(); } );
jQuery( '#comment-form-identity' ).slideDown();
jQuery( '#comment-form-subscribe' ).slideDown();
jQuery( '#commentform .form-submit' ).slideDown();
});
}
jQuery(document).ready( highlander_expando_javascript );
</script>
<div id="comment-form-subscribe">
<p class="comment-subscription-form"><input type="checkbox" name="subscribe" id="subscribe" value="subscribe" style="width: auto;" tabindex="6"/> <label class="subscribe-label" id="subscribe-label" for="subscribe" style="display: inline;">Notify me of new comments via email.</label></p><p class="post-subscription-form"><input type="checkbox" name="subscribe_blog" id="subscribe_blog" value="subscribe" style="width: auto;" tabindex="7"/> <label class="subscribe-label" id="subscribe-blog-label" for="subscribe_blog" style="display: inline;">Notify me of new posts via email.</label></p></div>
<p class="form-submit"><input name="submit" type="submit" id="comment-submit" class="submit" value="Post Comment" /> <input type='hidden' name='comment_post_ID' value='229' id='comment_post_ID' />
<input type='hidden' name='comment_parent' id='comment_parent' value='0' />
</p><p style="display: none;"><input type="hidden" id="akismet_comment_nonce" name="akismet_comment_nonce" value="6e0a374949" /></p>
<input type="hidden" name="genseq" value="1451643497" />
<p style="display: none;"><input type="hidden" id="ak_js" name="ak_js" value="166"/></p> </form>
</div><!-- #respond -->
<div style="clear: both"></div>
</div><!-- #comments --> </div>
</div>
<div id="sidebar">
<div id="top-posts-2" class="widget widget_top-posts"><h4>Top Posts</h4><ul><li><a href="https://marcmutz.wordpress.com/effective-qt/containers/" class="bump-view" data-bump-view="tp">Understand the Qt containers</a></li>
<li><a href="https://marcmutz.wordpress.com/effective-qt/subclassing/" class="bump-view" data-bump-view="tp">Don't be sub-class when subclassing</a></li>
<li><a href="https://marcmutz.wordpress.com/2010/10/14/top-5-reasons-you-should-love-your-ternary-operator/" class="bump-view" data-bump-view="tp">Top 5 reasons you should love your ternary operator</a></li>
<li><a href="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/" class="bump-view" data-bump-view="tp">Pimp My Pimpl</a></li>
<li><a href="https://marcmutz.wordpress.com/private-practice/whats-in-a-proxy-style/" class="bump-view" data-bump-view="tp">What's in a Proxy-Style?</a></li>
</ul></div><div id="tag_cloud-2" class="widget widget_tag_cloud"><h4></h4><div style="overflow: hidden;"><a href="https://marcmutz.wordpress.com/category/projects/akonadi/" style="font-size: 100%; padding: 1px; margin: 1px;" title="Akonadi (1)">Akonadi</a> <a href="https://marcmutz.wordpress.com/category/software-libraries/boost/" style="font-size: 135%; padding: 1px; margin: 1px;" title="Boost (6)">Boost</a> <a href="https://marcmutz.wordpress.com/category/programming-languages/c/" style="font-size: 268%; padding: 1px; margin: 1px;" title="C++ (25)">C++</a> <a href="https://marcmutz.wordpress.com/category/programming-languages/c/c0x/" style="font-size: 170%; padding: 1px; margin: 1px;" title="C++0x (11)">C++0x</a> <a href="https://marcmutz.wordpress.com/category/columns/effective-qt/" style="font-size: 128%; padding: 1px; margin: 1px;" title="Effective Qt (5)">Effective Qt</a> <a href="https://marcmutz.wordpress.com/category/english/" style="font-size: 275%; padding: 1px; margin: 1px;" title="English (26)">English</a> <a href="https://marcmutz.wordpress.com/category/german/" style="font-size: 198%; padding: 1px; margin: 1px;" title="German (15)">German</a> <a href="https://marcmutz.wordpress.com/category/projects/gpg4win/" style="font-size: 121%; padding: 1px; margin: 1px;" title="Gpg4win (4)">Gpg4win</a> <a href="https://marcmutz.wordpress.com/category/columns/heise-developer/" style="font-size: 149%; padding: 1px; margin: 1px;" title="Heise Developer (8)">Heise Developer</a> <a href="https://marcmutz.wordpress.com/category/columns/private-practice/" style="font-size: 114%; padding: 1px; margin: 1px;" title="Private Practice (3)">Private Practice</a> <a href="https://marcmutz.wordpress.com/category/software-libraries/qt/" style="font-size: 205%; padding: 1px; margin: 1px;" title="Qt (16)">Qt</a> </div></div><div id="image-3" class="widget widget_image"><h4>StackOverflow</h4><div style="overflow:hidden;"><a href="http://stackoverflow.com/users/134841/mmutz"><img src="http://stackoverflow.com/users/flair/134841.png?theme=clean" alt="profile for mmutz at Stack Overflow, Q&A for professional and enthusiast programmers" title="profile for mmutz at Stack Overflow, Q&A for professional and enthusiast programmers" class="alignright" width="208" height="58" /></a></div>
</div><div id="archives-3" class="widget widget_archive"><h4>Monthly</h4> <ul>
<li><a href='https://marcmutz.wordpress.com/2012/02/'>February 2012</a> (1)</li>
<li><a href='https://marcmutz.wordpress.com/2012/01/'>January 2012</a> (1)</li>
<li><a href='https://marcmutz.wordpress.com/2011/11/'>November 2011</a> (3)</li>
<li><a href='https://marcmutz.wordpress.com/2011/10/'>October 2011</a> (2)</li>
<li><a href='https://marcmutz.wordpress.com/2011/09/'>September 2011</a> (3)</li>
<li><a href='https://marcmutz.wordpress.com/2011/08/'>August 2011</a> (3)</li>
<li><a href='https://marcmutz.wordpress.com/2011/07/'>July 2011</a> (2)</li>
<li><a href='https://marcmutz.wordpress.com/2011/04/'>April 2011</a> (2)</li>
<li><a href='https://marcmutz.wordpress.com/2011/03/'>March 2011</a> (1)</li>
<li><a href='https://marcmutz.wordpress.com/2010/12/'>December 2010</a> (1)</li>
<li><a href='https://marcmutz.wordpress.com/2010/11/'>November 2010</a> (1)</li>
<li><a href='https://marcmutz.wordpress.com/2010/10/'>October 2010</a> (2)</li>
<li><a href='https://marcmutz.wordpress.com/2010/09/'>September 2010</a> (1)</li>
<li><a href='https://marcmutz.wordpress.com/2010/08/'>August 2010</a> (3)</li>
<li><a href='https://marcmutz.wordpress.com/2010/07/'>July 2010</a> (7)</li>
</ul>
</div><div id="linkcat-1356" class="widget widget_links"><h4>Blogroll</h4>
<ul class='xoxo blogroll'>
<li><a href="http://steveire.wordpress.com/">Stephen's Blog</a></li>
<li><a href="http://ervin.ipsquad.net/">Kevin's Blog</a></li>
<li><a href="http://c2143.blogspot.com/">Romain's Blog</a></li>
<li><a href="http://blogs.kde.org/blog/326">David's Blog</a></li>
<li><a href="http://thomasmcguire.wordpress.com/">Thomas' Blog</a></li>
</ul>
</div>
</div>
</div>
<div id="footer">
<div class="footerleft">
<p><a href="https://wordpress.com/?ref=footer_blog">Blog at WordPress.com.</a></p>
</div>
<div class="footerright">
<a href="https://wordpress.com/themes/enterprise/" title="Learn more about this theme">The Enterprise Theme</a>. </div>
</div>
</div>
<!-- wpcom_wp_footer -->
<script type='text/javascript' src='//0.gravatar.com/js/gprofiles.js?ver=201653y'></script>
<script type='text/javascript'>
/* <![CDATA[ */
var WPGroHo = {"my_hash":""};
/* ]]> */
</script>
<script type='text/javascript' src='https://s2.wp.com/wp-content/mu-plugins/gravatar-hovercards/wpgroho.js?m=1380573781g'></script>
<script>
//initialize and attach hovercards to all gravatars
jQuery( document ).ready( function( $ ) {
if (typeof Gravatar === "undefined"){
return;
}
if ( typeof Gravatar.init !== "function" ) {
return;
}
Gravatar.profile_cb = function( hash, id ) {
WPGroHo.syncProfileData( hash, id );
};
Gravatar.my_hash = WPGroHo.my_hash;
Gravatar.init( 'body', '#wp-admin-bar-my-account' );
});
</script>
<div style="display:none">
<div class="grofile-hash-map-b2feaf669090ecd1eba6049704bcc610">
</div>
<div class="grofile-hash-map-51b7f05de9889e7212f949f0fd975922">
</div>
<div class="grofile-hash-map-0ba3dff2713f82030e7f0fcbd719325a">
</div>
</div>
<script type='text/javascript'>
/* <![CDATA[ */
var HighlanderComments = {"loggingInText":"Logging In\u2026","submittingText":"Posting Comment\u2026","postCommentText":"Post Comment","connectingToText":"Connecting to %s","commentingAsText":"%1$s: You are commenting using your %2$s account.","logoutText":"Log Out","loginText":"Log In","connectURL":"https:\/\/marcmutz.wordpress.com\/public.api\/connect\/?action=request","logoutURL":"https:\/\/marcmutz.wordpress.com\/wp-login.php?action=logout&_wpnonce=c60a8cbcd3","homeURL":"https:\/\/marcmutz.wordpress.com\/","postID":"229","gravDefault":"identicon","enterACommentError":"Please enter a comment","enterEmailError":"Please enter your email address here","invalidEmailError":"Invalid email address","enterAuthorError":"Please enter your name here","gravatarFromEmail":"This picture will show whenever you leave a comment. Click to customize it.","logInToExternalAccount":"Log in to use details from one of these accounts.","change":"Change","changeAccount":"Change Account","comment_registration":"","userIsLoggedIn":"","isJetpack":"0","text_direction":"ltr"};
/* ]]> */
</script>
<script type='text/javascript' src='https://s2.wp.com/_static/??/wp-content/js/jquery/jquery.autoresize.js,/wp-content/mu-plugins/highlander-comments/script.js?m=1424115551j'></script>
<div id="bit" class="loggedout-follow-normal">
<a class="bsub" href="javascript:void(0)"><span id='bsub-text'>Follow</span></a>
<div id="bitsubscribe">
<h3><label for="loggedout-follow-field">Follow “-Wmarc”</label></h3>
<form action="https://subscribe.wordpress.com" method="post" accept-charset="utf-8" id="loggedout-follow">
<p>Get every new post delivered to your Inbox.</p>
<p id="loggedout-follow-error" style="display: none;"></p>
<p class="bit-follow-count">Join 26 other followers</p>
<p><input type="email" name="email" placeholder="Enter your email address" id="loggedout-follow-field"/></p>
<input type="hidden" name="action" value="subscribe"/>
<input type="hidden" name="blog_id" value="14776649"/>
<input type="hidden" name="source" value="https://marcmutz.wordpress.com/translated-articles/pimp-my-pimpl/"/>
<input type="hidden" name="sub-type" value="loggedout-follow"/>
<input type="hidden" id="_wpnonce" name="_wpnonce" value="f88de3158a" /><input type="hidden" name="_wp_http_referer" value="/translated-articles/pimp-my-pimpl/" />
<p id='bsub-subscribe-button'><input type="submit" value="Sign me up" /></p>
</form>
<div id='bsub-credit'><a href="https://wordpress.com/?ref=lof">Build a website with WordPress.com</a></div>
</div><!-- #bitsubscribe -->
</div><!-- #bit -->
<script type='text/javascript' charset='UTF-8' id='polldaddyRatings'><!--//--><![CDATA[//><!--
PDRTJS_settings_2480796_page_229={"id":2480796,"unique_id":"wp-page-229","title":"Pimp%20My%20Pimpl","permalink":"https:\/\/marcmutz.wordpress.com\/translated-articles\/pimp-my-pimpl\/","item_id":"_page_229"}; if ( typeof PDRTJS_RATING !== 'undefined' ){if ( typeof PDRTJS_2480796_page_229 == 'undefined' ){PDRTJS_2480796_page_229 = new PDRTJS_RATING( PDRTJS_settings_2480796_page_229 );}}
//--><!]]></script><script type='text/javascript' charset='UTF-8' src='https://polldaddy.com/js/rating/rating.js'></script>
<script type="text/javascript">
window.WPCOM_sharing_counts = {"https:\/\/marcmutz.wordpress.com\/translated-articles\/pimp-my-pimpl\/":229};
</script>
<script type="text/javascript">
var windowOpen;
jQuery(document).on( 'ready post-load', function(){
jQuery( 'a.share-twitter' ).on( 'click', function() {
if ( 'undefined' !== typeof windowOpen ){ // If there's another sharing window open, close it.
windowOpen.close();
}
windowOpen = window.open( jQuery(this).attr( 'href' ), 'wpcomtwitter', 'menubar=1,resizable=1,width=600,height=350' );
return false;
});
});
</script>
<script type="text/javascript">
var windowOpen;
jQuery(document).on( 'ready post-load', function(){
jQuery( 'a.share-google-plus-1' ).on( 'click', function() {
if ( 'undefined' !== typeof windowOpen ){ // If there's another sharing window open, close it.
windowOpen.close();
}
windowOpen = window.open( jQuery(this).attr( 'href' ), 'wpcomgoogle-plus-1', 'menubar=1,resizable=1,width=480,height=550' );
return false;
});
});
</script>
<div id="sharing_email" style="display: none;">
<form action="/translated-articles/pimp-my-pimpl/" method="post">
<label for="target_email">Send to Email Address</label>
<input type="email" name="target_email" id="target_email" value="" />
<label for="source_name">Your Name</label>
<input type="text" name="source_name" id="source_name" value="" />
<label for="source_email">Your Email Address</label>
<input type="email" name="source_email" id="source_email" value="" />
<input type="text" id="jetpack-source_f_name" name="source_f_name" class="input" value="" size="25" autocomplete="off" />
<script> document.getElementById('jetpack-source_f_name').value = ''; </script>
<div class="recaptcha" id="sharing_recaptcha"></div><input type="hidden" name="recaptcha_public_key" id="recaptcha_public_key" value="6LcYW8MSAAAAADBAuEH9yaPcF7lWh11Iq62ZKtoo" />
<img style="float: right; display: none" class="loading" src="https://s2.wp.com/wp-content/mu-plugins/post-flair/sharing/images/loading.gif" alt="loading" width="16" height="16" />
<input type="submit" value="Send Email" class="sharing_send" />
<a rel="nofollow" href="#cancel" class="sharing_cancel">Cancel</a>
<div class="errors errors-1" style="display: none;">
Post was not sent - check your email addresses! </div>
<div class="errors errors-2" style="display: none;">
Email check failed, please try again </div>
<div class="errors errors-3" style="display: none;">
Sorry, your blog cannot share posts by email. </div>
</form>
</div>
<iframe src='https://widgets.wp.com/likes/master.html?ver=20151208#ver=20151208&mp6=1' scrolling='no' id='likes-master' name='likes-master' style='display:none;'></iframe>
<div id='likes-other-gravatars'><div class="likes-text"><span>%d</span> bloggers like this:</div><ul class="wpl-avatars sd-like-gravatars"></ul></div>
<script type="text/javascript">
//<![CDATA[
var jetpackLikesWidgetQueue = [];
var jetpackLikesWidgetBatch = [];
var jetpackLikesMasterReady = false;
function JetpackLikespostMessage( message, target ) {
if ( "string" === typeof message ){
try{
message = JSON.parse( message );
}
catch(e) {
return;
}
}
pm( {
target: target,
type: 'likesMessage',
data: message,
origin: '*'
} );
}
function JetpackLikesBatchHandler() {
var requests = [];
jQuery( 'div.jetpack-likes-widget-unloaded' ).each( function( i ) {
if ( jetpackLikesWidgetBatch.indexOf( this.id ) > -1 )
return;
jetpackLikesWidgetBatch.push( this.id );
var regex = /like-(post|comment)-wrapper-(\d+)-(\d+)-(\w+)/;
var match = regex.exec( this.id );
if ( ! match || match.length != 5 )
return;
var info = {
blog_id: match[2],
width: this.width
};
if ( 'post' == match[1] ) {
info.post_id = match[3];
} else if ( 'comment' == match[1] ) {
info.comment_id = match[3];
}
info.obj_id = match[4];
requests.push( info );
});
if ( requests.length > 0 ) {
JetpackLikespostMessage( { event: 'initialBatch', requests: requests }, window.frames['likes-master'] );
}
}
function JetpackLikesMessageListener( event ) {
if ( "undefined" == typeof event.event )
return;
if ( 'masterReady' == event.event ) {
jQuery( document ).ready( function() {
jetpackLikesMasterReady = true;
var stylesData = {
event: 'injectStyles'
};
if ( jQuery( 'iframe.admin-bar-likes-widget' ).length > 0 ) {
JetpackLikespostMessage( { event: 'adminBarEnabled' }, window.frames[ 'likes-master' ] );
stylesData.adminBarStyles = {
background: jQuery( '#wpadminbar .quicklinks li#wp-admin-bar-wpl-like > a' ).css( 'background' ),
isRtl: ( 'rtl' == jQuery( '#wpadminbar' ).css( 'direction' ) )
};
}