PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > Pimpl idiom without dynamic memory allocation
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Pimpl idiom without dynamic memory allocation

Réponse
 
LinkBack Outils de la discussion
Vieux 17/10/2007, 19h29   #1
Daniel Lidström
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Pimpl idiom without dynamic memory allocation

Hello!

I have just discovered a way to use the private implementation idiom
(pimpl), without the overhead of dynamic memory allocation. For those of
you who don't know what this is, Wikipedia has a nice article you can
read. Anyway, I discovered that if you make all members in the
implementation class mutable, you can in fact use this idiom without any
"unnecessary" memory allocation. Here's a minimal example of the method:

// In the header of your class called Line

#include <string>

class Line
{
public:

Line(const std::string& name);
const std::string& GetName() const;
void SetName(const std::string& s);

private:

// Private implementation idiom:
// all member variables are hidden in this class
class LineImpl;
const LineImpl& m_pimpl; // normally a non-const pointer
};

// and in your implementation file:

#include "Line.h"

// Here we define the class with the member variables
class Line::LineImpl
{
public:

LineImpl(const std::string& s) : m_s(s) {}
// all methods need to be const here
const std::string& GetName() const { return m_s; }
void SetName(const std::string& s) const { m_s = s; }

private:

mutable std::string m_s; // the trick! all members are mutable
};

// create the pimpl instance without using new
Line::Line(const std::string& s) : m_pimpl(LineImpl(s)) {}

// forward all member functions to the private implementation
const std::string& Line::GetName() const
{
return m_pimpl.GetName();
}

void Line::SetName(const std::string& s)
{
m_pimpl.SetName(s);
}

Ok experts, what do you all think? This method sacrifies
const-correctness for some extra speed. Is it worth it?

--
Daniel
  Réponse avec citation
Vieux 17/10/2007, 19h45   #2
Michael DOUBEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

Daniel Lidström a écrit :
> Hello!
>
> I have just discovered a way to use the private implementation idiom
> (pimpl), without the overhead of dynamic memory allocation. For those of
> you who don't know what this is, Wikipedia has a nice article you can
> read. Anyway, I discovered that if you make all members in the
> implementation class mutable, you can in fact use this idiom without any
> "unnecessary" memory allocation. Here's a minimal example of the method:
>
> // In the header of your class called Line
>
> #include <string>
>
> class Line
> {
> public:
>
> Line(const std::string& name);
> const std::string& GetName() const;
> void SetName(const std::string& s);
>
> private:
>
> // Private implementation idiom:
> // all member variables are hidden in this class
> class LineImpl;
> const LineImpl& m_pimpl; // normally a non-const pointer
> };
>
> // and in your implementation file:
>
> #include "Line.h"
>
> // Here we define the class with the member variables

[snip]
> // all methods need to be const here

[snip]
> mutable std::string m_s; // the trick! all members are mutable


Which mean you coerce the code into compilation. That's all.

> // create the pimpl instance without using new
> Line::Line(const std::string& s) : m_pimpl(LineImpl(s)) {}


Your local is destroyed when going out of scope. Doesn't it ?

> [snip]
> Ok experts, what do you all think? This method sacrifies
> const-correctness for some extra speed. Is it worth it?


Not really.
And certainly not worth a dangling reference.


Michael
  Réponse avec citation
Vieux 17/10/2007, 20h07   #3
Daniel Lidström
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

In article <4716585e$0$25087$426a74cc@news.free.fr>,
Michael DOUBEZ <michael.doubez@free.fr> wrote:

> Daniel Lidström a écrit :
> > // create the pimpl instance without using new
> > Line::Line(const std::string& s) : m_pimpl(LineImpl(s)) {}

>
> Your local is destroyed when going out of scope. Doesn't it ?


No it isn't. It is actually ok to bind a temporary object to a const
reference. There will be no "dangling" reference.

--
Daniel
  Réponse avec citation
Vieux 17/10/2007, 20h09   #4
Michael DOUBEZ
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

Daniel Lidström a écrit :
> In article <4716585e$0$25087$426a74cc@news.free.fr>,
> Michael DOUBEZ <michael.doubez@free.fr> wrote:
>
>> Daniel Lidström a écrit :
>>> // create the pimpl instance without using new
>>> Line::Line(const std::string& s) : m_pimpl(LineImpl(s)) {}

>> Your local is destroyed when going out of scope. Doesn't it ?

>
> No it isn't. It is actually ok to bind a temporary object to a const
> reference. There will be no "dangling" reference.


It is ok to bind it but that doesn't mean the lifetime of the temporary
is extended.

Example:
const std::string& foo()
{
return std::string("bar");
}

The value returned by foo() is an dangling reference.

Michael

  Réponse avec citation
Vieux 17/10/2007, 21h36   #5
Daniel T.
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

Daniel Lidström <somebody@microsoft.com> wrote:

> // In the header of your class called Line
>
> #include <string>
>
> class Line
> {
> public:
>
> Line(const std::string& name);
> const std::string& GetName() const;
> void SetName(const std::string& s);
>
> private:
>
> // Private implementation idiom:
> // all member variables are hidden in this class
> class LineImpl;
> const LineImpl& m_pimpl; // normally a non-const pointer
> };
>
> // and in your implementation file:
>
> #include "Line.h"
>
> // Here we define the class with the member variables
> class Line::LineImpl
> {
> public:
>
> LineImpl(const std::string& s) : m_s(s) {}
> // all methods need to be const here
> const std::string& GetName() const { return m_s; }
> void SetName(const std::string& s) const { m_s = s; }
>
> private:
>
> mutable std::string m_s; // the trick! all members are mutable
> };
>
> // create the pimpl instance without using new
> Line::Line(const std::string& s) : m_pimpl(LineImpl(s)) {}


Where would the memory for the LineImpl object be placed? It isn't
embedded in the object, nor is it in the heap, and it can't be placed on
the stack (and still survive the call to the c_tor.)

Doesn't sound like a good idea to me.
  Réponse avec citation
Vieux 18/10/2007, 08h42   #6
Ulrich Eckhardt
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

Daniel Lidström wrote:
> I have just discovered a way to use the private implementation idiom
> (pimpl), without the overhead of dynamic memory allocation.

[ storing a reference to a temporary ]

As you noticed, this doesn't work. However, there is a method that works.
All you have to do is to add a suitably aligned and sufficiently large
buffer into the class:

class foo {
aligned_storage<42> m_impl;
class implementation;
foo();
~foo();
void some_function();
};

class foo::implementation { ... };

foo::foo() {
// placement new
new m_impl.get<void>() implementation;
}
foo::~foo() {
// explicit dtor invokation
m_impl.get<implementation>()->~implementation;
}
void foo::some_function() {
m_impl.get<implementation>()->some_function();
}

Is it worth the hassle? Typically not, in particular since it's hard to
guarantee that you have both enough but still not too much memory.

Uli

  Réponse avec citation
Vieux 18/10/2007, 11h09   #7
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

On Oct 17, 10:36 pm, "Daniel T." <danie...@earthlink.net> wrote:
> Daniel Lidström <someb...@microsoft.com> wrote:
> > // In the header of your class called Line


> > #include <string>


> > class Line
> > {
> > public:
> > Line(const std::string& name);
> > const std::string& GetName() const;
> > void SetName(const std::string& s);


> > private:
> > // Private implementation idiom:
> > // all member variables are hidden in this class
> > class LineImpl;
> > const LineImpl& m_pimpl; // normally a non-const pointer
> > };


> > // and in your implementation file:


> > #include "Line.h"


> > // Here we define the class with the member variables
> > class Line::LineImpl
> > {
> > public:
> > LineImpl(const std::string& s) : m_s(s) {}
> > // all methods need to be const here
> > const std::string& GetName() const { return m_s; }
> > void SetName(const std::string& s) const { m_s = s; }
> > private:
> > mutable std::string m_s; // the trick! all members are mutable
> > };


> > // create the pimpl instance without using new
> > Line::Line(const std::string& s) : m_pimpl(LineImpl(s)) {}


> Where would the memory for the LineImpl object be placed? It
> isn't embedded in the object, nor is it in the heap, and it
> can't be placed on the stack (and still survive the call to
> the c_tor.)


>From the standard (§12.2/5): "A temporary bound to a reference

member in a constructor's ctor-initializer persists until the
constructor exits." In colloquial terms: the temporary is
created on the stack, and destructed before returning from the
constructor.

> Doesn't sound like a good idea to me.


It isn't, unless you like undefined behavior and hard to find
bugs.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


  Réponse avec citation
Vieux 18/10/2007, 14h59   #8
Yannick Tremblay
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

In article <47165e09$0$26728$426a74cc@news.free.fr>,
Michael DOUBEZ <michael.doubez@free.fr> wrote:
>Daniel Lidström a écrit :
>> In article <4716585e$0$25087$426a74cc@news.free.fr>,
>> Michael DOUBEZ <michael.doubez@free.fr> wrote:
>>
>>> Daniel Lidström a écrit :
>>>> // create the pimpl instance without using new
>>>> Line::Line(const std::string& s) : m_pimpl(LineImpl(s)) {}
>>> Your local is destroyed when going out of scope. Doesn't it ?

>>
>> No it isn't. It is actually ok to bind a temporary object to a const
>> reference. There will be no "dangling" reference.

>
>It is ok to bind it but that doesn't mean the lifetime of the temporary
>is extended.
>
>Example:
>const std::string& foo()
>{
> return std::string("bar");
>}
>
>The value returned by foo() is an dangling reference.
>


Euh, it's not what he is doing, it's more like:

std::string foo()
{
return std::string("bar");
}

int main()
{
std::string const & val = foo();
....


  Réponse avec citation
Vieux 18/10/2007, 15h35   #9
Kai-Uwe Bux
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

Yannick Tremblay wrote:

> In article <47165e09$0$26728$426a74cc@news.free.fr>,
> Michael DOUBEZ <michael.doubez@free.fr> wrote:
>>Daniel Lidström a écrit :
>>> In article <4716585e$0$25087$426a74cc@news.free.fr>,
>>> Michael DOUBEZ <michael.doubez@free.fr> wrote:
>>>
>>>> Daniel Lidström a écrit :
>>>>> // create the pimpl instance without using new
>>>>> Line::Line(const std::string& s) : m_pimpl(LineImpl(s)) {}
>>>> Your local is destroyed when going out of scope. Doesn't it ?
>>>
>>> No it isn't. It is actually ok to bind a temporary object to a const
>>> reference. There will be no "dangling" reference.

>>
>>It is ok to bind it but that doesn't mean the lifetime of the temporary
>>is extended.
>>
>>Example:
>>const std::string& foo()
>>{
>> return std::string("bar");
>>}
>>
>>The value returned by foo() is an dangling reference.
>>

>
> Euh, it's not what he is doing, it's more like:
>
> std::string foo()
> {
> return std::string("bar");
> }
>
> int main()
> {
> std::string const & val = foo();
> ...


It's neither. What he is doing is initialzing a reference member from a
temporary object. The lifetime of that object lasts exactly to the end of
the constructor call. Afterwards, i.e., for the entire lifetime of the
fully constructed object, the reference is dangling. From the standard:

[...] A temporary bound to a reference member in a constructor?s
ctor-initializer (12.6.2) persists until the constructor exits. ...
[12.2/5]

This provision makes you wonder. What is the point of restricting the
life-time of the temporary to the duration of the constructor if the object
thus initialized is bound to have a dangling reference ever after?


Best

Kai-Uwe Bux
  Réponse avec citation
Vieux 18/10/2007, 16h08   #10
Joe Greer
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

Kai-Uwe Bux <jkherciueh@gmx.net> wrote in
news:ff7r0f$rg6$1@murdoch.acc.Virginia.EDU:

> It's neither. What he is doing is initialzing a reference member from
> a temporary object. The lifetime of that object lasts exactly to the
> end of the constructor call. Afterwards, i.e., for the entire lifetime
> of the fully constructed object, the reference is dangling. From the
> standard:
>
> [...] A temporary bound to a reference member in a constructor?s
> ctor-initializer (12.6.2) persists until the constructor exits. ...
> [12.2/5]
>
> This provision makes you wonder. What is the point of restricting the
> life-time of the temporary to the duration of the constructor if the
> object thus initialized is bound to have a dangling reference ever
> after?
>


It is interesting. I would have thought that it would last until the scope
in which the constructor was invoked exited and the stack space is
reclaimed. There is probably some case for creating the temporaries within
the scope of the constructor or something that I don't see at the moment.
In any case, I can't see this for the pimpl idiom.

joe
  Réponse avec citation
Vieux 18/10/2007, 16h45   #11
Andre Kostur
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

Kai-Uwe Bux <jkherciueh@gmx.net> wrote in
news:ff7r0f$rg6$1@murdoch.acc.Virginia.EDU:

> Yannick Tremblay wrote:
>
>> In article <47165e09$0$26728$426a74cc@news.free.fr>,
>> Michael DOUBEZ <michael.doubez@free.fr> wrote:
>>>Daniel Lidström a écrit :
>>>> In article <4716585e$0$25087$426a74cc@news.free.fr>,
>>>> Michael DOUBEZ <michael.doubez@free.fr> wrote:
>>>>
>>>>> Daniel Lidström a écrit :
>>>>>> // create the pimpl instance without using new
>>>>>> Line::Line(const std::string& s) : m_pimpl(LineImpl(s)) {}
>>>>> Your local is destroyed when going out of scope. Doesn't it ?
>>>>
>>>> No it isn't. It is actually ok to bind a temporary object to a
>>>> const reference. There will be no "dangling" reference.
>>>
>>>It is ok to bind it but that doesn't mean the lifetime of the
>>>temporary is extended.
>>>
>>>Example:
>>>const std::string& foo()
>>>{
>>> return std::string("bar");
>>>}
>>>
>>>The value returned by foo() is an dangling reference.
>>>

>>
>> Euh, it's not what he is doing, it's more like:
>>
>> std::string foo()
>> {
>> return std::string("bar");
>> }
>>
>> int main()
>> {
>> std::string const & val = foo();
>> ...

>
> It's neither. What he is doing is initialzing a reference member from
> a temporary object. The lifetime of that object lasts exactly to the
> end of the constructor call. Afterwards, i.e., for the entire lifetime
> of the fully constructed object, the reference is dangling. From the
> standard:
>
> [...] A temporary bound to a reference member in a constructor?s
> ctor-initializer (12.6.2) persists until the constructor exits. ...
> [12.2/5]
>
> This provision makes you wonder. What is the point of restricting the
> life-time of the temporary to the duration of the constructor if the
> object thus initialized is bound to have a dangling reference ever
> after?


I don't have the Standard handy... but does it change the details since
it's a const-reference?
  Réponse avec citation
Vieux 18/10/2007, 18h54   #12
Joe Greer
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

Andre Kostur <nntpspam@kostur.net> wrote in news:Xns99CD599F98AC5nntpspamkosutrnet@
209.135.99.21:

>
> I don't have the Standard handy... but does it change the details since
> it's a const-reference?
>


As far as I can tell from the standard, it doesn't. In my own personal mind's eye of how things
work, I always imagine temporaries allocated on the stack and as soon as the appropriate stack
scope is gone, so is the temporary. I don't think that temporaries have to be on the stack, but
the implementations I have looked at act as though they are.

joe
  Réponse avec citation
Vieux 19/10/2007, 08h53   #13
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

On Oct 18, 4:35 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Yannick Tremblay wrote:


> It's neither. What he is doing is initialzing a reference
> member from a temporary object. The lifetime of that object
> lasts exactly to the end of the constructor call. Afterwards,
> i.e., for the entire lifetime of the fully constructed object,
> the reference is dangling. From the standard:


> [...] A temporary bound to a reference member in a constructor?s
> ctor-initializer (12.6.2) persists until the constructor exits. ...
> [12.2/5]


> This provision makes you wonder. What is the point of
> restricting the life-time of the temporary to the duration of
> the constructor if the object thus initialized is bound to
> have a dangling reference ever after?


Implementation constraints: where would the compiler put the
temporary if it were required to outlast the constructor? (I
suppose that the standard could have made it illegal to
initialize a reference member with a temporary.)

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

  Réponse avec citation
Vieux 19/10/2007, 08h55   #14
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

On Oct 18, 5:45 pm, Andre Kostur <nntps...@kostur.net> wrote:
> Kai-Uwe Bux <jkherci...@gmx.net> wrote
> innews:ff7r0f$rg6$1@murdoch.acc.Virginia.EDU:
> > It's neither. What he is doing is initialzing a reference member from
> > a temporary object. The lifetime of that object lasts exactly to the
> > end of the constructor call. Afterwards, i.e., for the entire lifetime
> > of the fully constructed object, the reference is dangling. From the
> > standard:


> > [...] A temporary bound to a reference member in a constructor?s
> > ctor-initializer (12.6.2) persists until the constructor exits. ...
> > [12.2/5]


> > This provision makes you wonder. What is the point of restricting the
> > life-time of the temporary to the duration of the constructor if the
> > object thus initialized is bound to have a dangling reference ever
> > after?


> I don't have the Standard handy... but does it change the details since
> it's a const-reference?


Yes. If the reference isn't to const, it can't be initialized
with a temporary at all, so the lifetime of such a temporary
doesn't have any meaning.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

  Réponse avec citation
Vieux 19/10/2007, 08h57   #15
James Kanze
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

On Oct 18, 5:08 pm, Joe Greer <jgr...@doubletake.com> wrote:
> Kai-Uwe Bux <jkherci...@gmx.net> wrote
> innews:ff7r0f$rg6$1@murdoch.acc.Virginia.EDU:


> > It's neither. What he is doing is initialzing a reference member from
> > a temporary object. The lifetime of that object lasts exactly to the
> > end of the constructor call. Afterwards, i.e., for the entire lifetime
> > of the fully constructed object, the reference is dangling. From the
> > standard:


> > [...] A temporary bound to a reference member in a constructor?s
> > ctor-initializer (12.6.2) persists until the constructor exits. ...
> > [12.2/5]


> > This provision makes you wonder. What is the point of restricting the
> > life-time of the temporary to the duration of the constructor if the
> > object thus initialized is bound to have a dangling reference ever
> > after?


> It is interesting. I would have thought that it would last until the scope
> in which the constructor was invoked exited and the stack space is
> reclaimed. There is probably some case for creating the temporaries within
> the scope of the constructor or something that I don't see at the moment.
> In any case, I can't see this for the pimpl idiom.


The temporary is created in the constructor, not in the code
which calls the constructor. The code which calls the
constructor doesn't even know that the temporary might exist.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

  Réponse avec citation
Vieux 01/11/2007, 00h51   #16
Brendon Costa
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Pimpl idiom without dynamic memory allocation

I noticed above that there was a suggestion using:
aligned_storage<..>. From my understanding this class does not exit in
the current C++ standard but is being considered for C++0x ? Also is
there any runtime overhead caused by the overloaded operator -> in
that implementation. If not then it it probably a much better
implementation than what i started working on last night...

Following on from this thread, i have been working on an
implementation of the PIMPL pattern that i think will work by
allocating correctly on the stack. Would others be able to take a look
at it and let me know if this will fail? I have tested it with GCC on
linux + MinGW and MSVC. The point of this is to try and remove the
small runtime penalty from the pointer dereference with the typical
PImpl implementation.

I have created a number of macros that will let me achieve this simply
using a single class definition which using macro trickery changes the
internals of the class between the header presented to the public and
the cpp file that implements the internals. But for demonstration i
will give the code for a header and cpp file as simple as possible
with no macros. I have also removed a number of compile time checks
that are in the macro version.

The basic concept is that the public implementation looks just like a
lump of aligned memory (char array in this case) and defines calls to
constructors/destructor and assignment operator which must not be
implicit or inline. These are used to "initialise"/"destroy" that lump
of memory. In the private implementation this lump of aligned memory
actually looks like a class with a little bit left over. So the class
itself looks different based on where you are looking at it from. I
dont like this, but can not see a way of avoiding it.

The macro implementation also uses different methods to align the
array for different compilers. Following is a list of possible issues
i can see with this:

* Requires compiler specific implementation for variable alignment
(There is a generic one that attempts to place a union of various data
types just before the char array in order to try and align it
correctly. This is wasteful of memory but i "think" will work for
compilers i haven;t handled with variable alignment specifications
like GCC below)

* If the compiler produces padding between the Implementation instance
in the cpp file and the char array that follows, then the size of the
StackPImpl in the cpp file will differ from its size in the public
causing all sorts of problems.

- I dont know if this will ever occur. It will only occur if the
sizeof(StackPImpl_IMPL) is such that the alignment of a char array
will require padding before it.
- Could be solved again by defining the char array in the private
implementation as not being aligned

* Will have size issues on systems where sizeof(char) != 1
- May fix by defining size of array as array[SIZE / sizeof(char) +
1]


Would people be able to take a look at this and let me know if they
can for-see any issues?

Thanks,
Brendon.

--- header ---
#define SIZE 8
class StackPImpl
{
public:
StackPImpl();
~StackPImpl();
StackPImpl(const StackPImpl& right);
StackPImpl& operator=(const StackPImpl& right);
void Public();

unsigned char pimpl_data[SIZE] __attribute__((aligned));
};





--- cpp implementation ---
class StackPImpl_IMPL
{
public:
int data;
};


#define SIZE 8
class StackPImpl
{
public:
StackPImpl();
~StackPImpl();
void Public();

StackPImpl_IMPL pimpl __attribute__((aligned));
unsigned char pimpl_data[SIZE - sizeof(StackPImpl_IMPL)];
};


StackPImpl::StackPImpl()
{
}

StackPImpl::~StackPImpl()
{
}

// @@@Brendon Could not be bothered implementing operator= and copy
for this eg

void StackPImpl::Public()
{
pimpl.data++;
}

  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 17h42.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,26802 seconds with 24 queries