Reputation: 11
I have following third-party class(just wrapper around some pointer):
// a.h
class AImpl;
class A
{
AImpl* pImpl;
public:
A(): pImpl(0) {}
A(AImpl* ptr): pImpl(ptr) {}
...
AImpl* getImpl() const { return pImpl; }
...
void someMethodOfA();
};
I want to modify A
's interface: disable some methods, add some new, while hiding its implementation details. I decided to do following:
// new_a.h
class AImpl;
class A;
class NewA
{
AImpl* pImpl;
public:
NewA( const A& a );
...
void newMethodOfA();
...
};
//new_a.cpp
#include "a.h"
NewA::NewA( const A& a ): pImpl( a.getImpl() ) {}
...
void NewA::newMethodOfA()
{
A( pImpl ).someMethodOfA();
}
...
Is it ok to do so? Maybe there is better solution? I want to change A
interface because it doesn't fit my needs and don't want to keep it in my own code.
Upvotes: 0
Views: 255
Reputation: 13378
In a comment you say that
I don't want to allocate A and hold A* pImpl, because it's already a wrapper around some pointer (AImpl)
Despite this requirement, you allocate a temporary A
object in NewA::newMethodOfA()
. In what way is this supposed to be better than allocating A
once and just re-use it? Your solution is not good because 1) you create a new temporary A
over and over again, and 2) you force the users of NewA
to provide an instance of A
instead of just creating one yourself.
I suggest you bite the bullet and just make a proper "PIMPL on top of PIMPL" implementation (as Captain Obvlious puts it):
// new_a.h
class A;
class NewA
{
A* pImpl;
public:
NewA();
~NewA();
void newMethodOfA();
};
//new_a.cpp
#include "a.h"
NewA::NewA() : pImpl( new A() ) {}
NewA::~NewA() { delete pImpl; }
void NewA::newMethodOfA()
{
pImpl->someMethodOfA();
}
This meets all your other requirements:
a.h
included in new_a.h
A
so users of NewA
won't know anything about A
and AImpl
A
The only thing that doesn't quite meet up is that in the code you show the default constructor of A
initializes its pImpl
member to 0 - this is weird! Since when is the user of a PIMPL class required to provide the object that is wrapped by the PIMPL class? Cf. Wikipedia's Opaque Pointer article.
Upvotes: 1