473,402 Members | 2,061 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,402 software developers and data experts.

Pimpl using auto_ptr


I've been beating my head against this for a while, so I'm now looking
for some hints and tips from the cognocenti...

I've been playing around with auto_ptr and as an exercise I've tried
to change a class of my own which uses the Pimpl idiom.

The original version is something like this:

//x.h
class MyClass
{
<snip stuff>
private:
class MyPrivate; // forward declaration
MyPrivate* p_;
};

//x.cc
// Constructor
MyClass::MyClass : p_(new MyPrivate()) {}

// Copy Constructor
MyClass::MyClass(const MyClass& that) : p_(new MyClass(*that.p_)) {}

// Assignment operator
MyClass&
MyClass::operator=(const MyClass& rhs)
{
MyPrivate* t_ = new MyPrivate(*rhs.p_);
delete p_;
p_ = t_;
return *this;
}

The problem is I can't see for the life of me how to write the copy
constructor and assignment operator if I change the declaration of p_
to this:

//x.h
class MyClass
{
<snip>
private:
class MyPrivate; // forward declaration
std::auto_ptr<MyPrivatep_;
};

Is there a 'canonical form' for expressing these?
TIA!
--
PGP key ID 0xEB7180EC
Nov 7 '07 #1
5 2317
On Nov 7, 12:00 pm, Keith Willis <m...@privacy.netwrote:
I've been beating my head against this for a while, so I'm now looking
for some hints and tips from the cognocenti...

I've been playing around with auto_ptr and as an exercise I've tried
to change a class of my own which uses the Pimpl idiom.

The original version is something like this:

//x.h
class MyClass
{
<snip stuff>
private:
class MyPrivate; // forward declaration
MyPrivate* p_;

};

//x.cc
// Constructor
MyClass::MyClass : p_(new MyPrivate()) {}

// Copy Constructor
MyClass::MyClass(const MyClass& that) : p_(new MyClass(*that.p_)) {}

// Assignment operator
MyClass&
MyClass::operator=(const MyClass& rhs)
{
MyPrivate* t_ = new MyPrivate(*rhs.p_);
delete p_;
p_ = t_;
return *this;

}

The problem is I can't see for the life of me how to write the copy
constructor and assignment operator if I change the declaration of p_
to this:

//x.h
class MyClass
{
<snip>
private:
class MyPrivate; // forward declaration
std::auto_ptr<MyPrivatep_;

};

Is there a 'canonical form' for expressing these?
TIA!
--
PGP key ID 0xEB7180EC
The existing code should almost work (although I haven't typed it in
and checked) except
you don't need to explicitly delete _p in your copy construtor. If
I'm not mistaken,
assigning an auto_ptr should delete what it previously points to.
Because of this
you should make an explicit check for self assignment and do nothing
if, in fact,
it is self assignment.

HTH

Nov 7 '07 #2
Keith Willis wrote:
I've been beating my head against this for a while, so I'm now looking
for some hints and tips from the cognocenti...
You haven't bang your head enough, cause your example suck. Anyway, take
a look at this:

#include <memory>
#include <iostream>

class MyClass
{
public:
MyClass(int a);
~MyClass();
MyClass(const MyClass& that);
MyClass& operator=(const MyClass& rhs);

void a() const;

private:
class MyPrivate; // forward declaration
std::auto_ptr< MyPrivate p_;
};

class MyClass::MyPrivate
{
public:
MyPrivate(){}
~MyPrivate(){}

int a;
};

//x.cc
// Constructor
MyClass::MyClass(int a) : p_(new MyPrivate)
{
p_->a=a;
}

MyClass::~MyClass()
{
}

// Copy Constructor
MyClass::MyClass(const MyClass& that)
{
this->p_.reset( new MyPrivate );
this->p_->a = that.p_->a;
}

// Assignment operator
MyClass& MyClass::operator=(const MyClass& rhs)
{
this->p_.reset( new MyPrivate );
this->p_->a = rhs.p_->a;
return *this;
}

void MyClass::a() const
{
std::cout<<p_->a<<std::endl;
}

int main()
{
MyClass a(2);
MyClass b(3);
a.a();
b.a();
a = b;
a.a();
b.a();
}
Nov 7 '07 #3
Alf P. Steinbach wrote:
* Keith Willis:
>I've been beating my head against this for a while, so I'm now looking
for some hints and tips from the cognocenti...

I've been playing around with auto_ptr and as an exercise I've tried
to change a class of my own which uses the Pimpl idiom.

std::auto_ptr requires a complete class. For the code to be valid you
can only use std::auto_ptr in PIMPL if all the relevant compilers
provide additional guarantees for std::auto_ptr. However, in practice
it might work.

Using std::auto_ptr for PIMPL is the most infamous error in the
(original) GOTW articles.

Look it up.
Yep. Sutter uses it in GOTW 59, 61, and 62.

I never realized that you couldn't use an auto_ptr on an incomplete
class. It doesn't really seem to need knowledge of the internals.

Nov 7 '07 #4
Alf P. Steinbach wrote:
>
Forgot to mention: for that workaround the public class also needs
non-inline constructor, so that the std::auto_ptr is constructed by the
code in the implementation file.
This is not necessary

struct X;
X* px = 0; // if this is not illformed -- condition1

<code>
#include <memory>

struct Wrapper {
Wrapper() : sp_(/*0*/) {}
~Wrapper();
private:
struct Impl;
std::auto_ptr<Implsp_;
};

struct Wrapper::Impl {};

Wrapper::~Wrapper() {}

int main()
{
Wrapper w;
}
</code>

if condition1 is true, then the code above is well-formed
And I think condition1 is true.

Nov 8 '07 #5
Barry <dh*****@gmail.comwrote in news:fg**********@news.cn99.com:
Alf P. Steinbach wrote:
>>
Forgot to mention: for that workaround the public class also needs
non-inline constructor, so that the std::auto_ptr is constructed by
the
>code in the implementation file.

This is not necessary

struct X;
X* px = 0; // if this is not illformed -- condition1

<code>
#include <memory>

struct Wrapper {
Wrapper() : sp_(/*0*/) {}
~Wrapper();
private:
struct Impl;
std::auto_ptr<Implsp_;
};

struct Wrapper::Impl {};

Wrapper::~Wrapper() {}

int main()
{
Wrapper w;
}
</code>

if condition1 is true, then the code above is well-formed
And I think condition1 is true.

It still doesn't necessarily know how to destroy an Impl, which I
believe is the problem. That is, if Impl has any sort of inheritance
heirarchy, it is likely that the inherited destructors won't be invoked
because the compiler doesn't know about them. There are also problems
if Impl is an abstract interface. At least, that is my experience.

joe
Nov 8 '07 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Icosahedron | last post by:
I've been going through some old code trying to clean it up and rearchitect it based on more modern C++ idioms. In the old code I often used the Pimpl idiom on a class by class basis, creating...
6
by: Asfand Yar Qazi | last post by:
Hi, Now that GCC 3.4 has precompiled headers, I'm thinking I can stop using pimpls to speed up development time, as it may make life easier (declaring pimpls takes a long time...) What are...
3
by: JackC | last post by:
Hi Problem: I wish to use a pimpl to hide implementation/storage of a class (T), but I also want to hold objects of that class (T) in an std::vector<T> (or similar). T is non trivial (i.e. not...
2
by: Peteris Krumins | last post by:
Hello! I was playing around pimpl idiom and discovered that there is a problem with it if a class member template function exists which has to access private data, since only the forward...
9
by: Edward Diener | last post by:
Because 'friend' is not recognized in MC++, using the pImpl idiom in MC++ classes seems nearly impossible. Normally a pImpl class is a 'friend' to the class for which it supplies the private...
10
by: red floyd | last post by:
It seems that the use of auto_ptr<> is discouraged in many places in favor of boost::shared_ptr<> (or tr1::shared_ptr<>). But consider a PIMPL idiom, where there is a strict 1-1 relationship...
34
by: Asfand Yar Qazi | last post by:
Hi, I'm creating a library where several classes are intertwined rather tightly. I'm thinking of making them all use pimpls, so that these circular dependancies can be avoided easily, and I'm...
4
by: er | last post by:
hi, the code below generates the following behavior. cld someone please help understand it? 1) clean project + build project generates build errors (see bottom) 2) build a second time, errors...
2
by: Graham Reitz | last post by:
What are good strategies for selecting, either at run-time or compile time, various pimpl'ed implementations? While retaining the ability to switch implementations without recompiling. Boost...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.