I am trying to use the pimpl pattern and define the implementation class in an anonymous namespace. Is this possible in C++? My failed attempt is described below.
Is it possible to fix this without moving the implementation into a namespace with a name (or the global one)?
class MyCalculatorImplementation;
class MyCalculator
{
public:
MyCalculator();
int CalculateStuff(int);
private:
MyCalculatorImplementation* pimpl;
};
namespace // If i omit the namespace, everything is OK
{
class MyCalculatorImplementation
{
public:
int Calculate(int input)
{
// Insert some complicated calculation here
}
private:
int state[100];
};
}
// error C2872: 'MyCalculatorImplementation' : ambiguous symbol
MyCalculator::MyCalculator(): pimpl(new MyCalculatorImplementation)
{
}
int MyCalculator::CalculateStuff(int x)
{
return pimpl->Calculate(x);
}
No, the type must be at least declared before the pointer type can be used, and putting anonymous namespace in the header won't really work. But why would you want to do that, anyway? If you really really want to hide the implementation class, make it a private inner class, i.e.
// .hpp
struct Foo {
Foo();
// ...
private:
struct FooImpl;
boost::scoped_ptr<FooImpl> pimpl;
};
// .cpp
struct Foo::FooImpl {
FooImpl();
// ...
};
Foo::Foo() : pimpl(new FooImpl) { }
Yes. There is a work around for this. Declare the pointer in the header file as void*, then use a reinterpret cast inside your implementation file.
Note: Whether this is a desirable work-around is another question altogether. As is often said, I will leave that as an exercise for the reader.
See a sample implementation below:
class MyCalculator
{
public:
MyCalculator();
int CalculateStuff(int);
private:
void* pimpl;
};
namespace // If i omit the namespace, everything is OK
{
class MyCalculatorImplementation
{
public:
int Calculate(int input)
{
// Insert some complicated calculation here
}
private:
int state[100];
};
}
MyCalculator::MyCalculator(): pimpl(new MyCalculatorImplementation)
{
}
MyCalaculator::~MyCalaculator()
{
// don't forget to cast back for destruction!
delete reinterpret_cast<MyCalculatorImplementation*>(pimpl);
}
int MyCalculator::CalculateStuff(int x)
{
return reinterpret_cast<MyCalculatorImplementation*>(pimpl)->Calculate(x);
}
No, you can't do that. You have to forward-declare the Pimpl class:
class MyCalculatorImplementation;
and that declares the class. If you then put the definition into the unnamed namespace, you are creating another class (anonymous namespace)::MyCalculatorImplementation, which has nothing to do with ::MyCalculatorImplementation.
If this was any other namespace NS, you could amend the forward-declaration to include the namespace:
namespace NS {
class MyCalculatorImplementation;
}
but the unnamed namespace, being as magic as it is, will resolve to something else when that header is included into other translation units (you'd be declaring a new class whenever you include that header into another translation unit).
But use of the anonymous namespace is not needed here: the class declaration may be public, but the definition, being in the implementation file, is only visible to code in the implementation file.
If you actually want a forward declared class name in your header file and the implementation in an anonymous namespace in the module file, then make the declared class an interface:
// header
class MyCalculatorInterface;
class MyCalculator{
...
MyCalculatorInterface* pimpl;
};
//module
class MyCalculatorInterface{
public:
virtual int Calculate(int) = 0;
};
int MyCalculator::CalculateStuff(int x)
{
return pimpl->Calculate(x);
}
namespace {
class MyCalculatorImplementation: public MyCalculatorInterface {
...
};
}
// Only the ctor needs to know about MyCalculatorImplementation
// in order to make a new one.
MyCalculator::MyCalculator(): pimpl(new MyCalculatorImplementation)
{
}
markshiz and quamrana provided the inspiration for the solution below.
class Implementation, is intended to be declared in a global header file and serves as a void* for any pimpl application in your code base. It is not in an anonymous/unnamed namespace, but since it only has a destructor the namespace pollution remains acceptably limited.
class MyCalculatorImplementation derives from class Implementation. Because pimpl is declared as std::unique_ptr<Implementation> there is no need to mention MyCalculatorImplementation in any header file. So now MyCalculatorImplementation can be implemented in an anonymous/unnamed namespace.
The gain is that all member definitions in MyCalculatorImplementation are in the anonymous/unnamed namespace. The price you have to pay, is that you must convert Implementation to MyCalculatorImplementation. For that purpose a conversion function toImpl() is provided.
I was doubting whether to use a dynamic_cast or a static_cast for the conversion. I guess the dynamic_cast is the typical prescribed solution; but static_cast will work here as well and is possibly a little more performant.
#include <memory>
class Implementation
{
public:
virtual ~Implementation() = 0;
};
inline Implementation::~Implementation() = default;
class MyCalculator
{
public:
MyCalculator();
int CalculateStuff(int);
private:
std::unique_ptr<Implementation> pimpl;
};
namespace // Anonymous
{
class MyCalculatorImplementation
: public Implementation
{
public:
int Calculate(int input)
{
// Insert some complicated calculation here
}
private:
int state[100];
};
MyCalculatorImplementation& toImpl(Implementation& impl)
{
return dynamic_cast<MyCalculatorImplementation&>(impl);
}
}
// no error C2872 anymore
MyCalculator::MyCalculator() : pimpl(std::make_unique<MyCalculatorImplementation>() )
{
}
int MyCalculator::CalculateStuff(int x)
{
return toImpl(*pimpl).Calculate(x);
}
Related
So consider I have a class with a private member variable and a private function which I do not want to define in the header file, because I want to "hide" it from the user.
How can I make this? I can not access the private variable without the declaration of the function in the header.
So what works is something like this:
// header file
class Testclass {
public:
// ...
private:
const int m_i;
void func() const;
}
// cpp file
#include "TestClass.h"
Testclass::func() const {
int j = m_i; //access to a private member variable
}
// ...
But I want something like this:
// header file
class Testclass{
public:
//...
private:
const int m_i;
}
// cpp file
#include "TestClass.h"
Testclass::func() const {
int j = m_i; //access to a private member variable
}
// ...
Which possibilities do I have? I read something about the PIMPL Idiom, but I am not sure if this is what I want, since it looks a bit cumbersome coding-wise.
You can have non-member helper functions in the cpp file, that the class members can use. However, they would have to pass the private variable as a parameter.
// header file
class Testclass{
public:
//...
private:
const int m_i;
}
// cpp file
#include "TestClass.h"
void func(int m_i) {
int j = m_i; //private member variable supplied by caller
}
// ...
Normally one achieves this through the PIMPL (Pointer to IMPLementation) idiom. In your header file you have:
class MainClass
{
public:
void public_function();
private:
class Impl;
Impl* impl;
};
Note that the header file does not contain the definition of the Impl class, only its declaration.
You then define that class in your cpp file and forward the calls from your public interface to the functions of the impl class:
class MainClass::Impl
{
void actualfunc()
{
//do useful stuff here
}
};
void MainClass::public_function()
{
return impl->actualfunc();
}
Apart from your indended hiding of unwanted members from your class users, the PIMPL idiom provides the additional benefit that if no changes are made to the interface of the class, the users of the class need not be recompiled.
There is no feature that control visibility/accessibility of class in C++.
Is there any way to fake it?
Are there any macro/template/magic of C++ that can simulate the closest behavior?
Here is the situation
Util.h (library)
class Util{
//note: by design, this Util is useful only for B and C
//Other classes should not even see "Util"
public: static void calculate(); //implementation in Util.cpp
};
B.h (library)
#include "Util.h"
class B{ /* ... complex thing */ };
C.h (library)
#include "Util.h"
class C{ /* ... complex thing */ };
D.h (user)
#include "B.h" //<--- Purpose of #include is to access "B", but not "Util"
class D{
public: static void a(){
Util::calculate(); //<--- should compile error
//When ctrl+space, I should not see "Util" as a choice.
}
};
My poor solution
Make all member of Util to be private, then declare :-
friend class B;
friend class C;
(Edit: Thank A.S.H for "no forward declaration needed here".)
Disadvantage :-
It is a modifying Util to somehow recognize B and C.
It doesn't make sense in my opinion.
Now B and C can access every member of Util, break any private access guard.
There is a way to enable friend for only some members but it is not so cute, and unusable for this case.
D just can't use Util, but can still see it.
Util is still a choice when use auto-complete (e.g. ctrl+space) in D.h.
(Edit) Note: It is all about convenience for coding; to prevent some bug or bad usage / better auto-completion / better encapsulation. This is not about anti-hacking, or prevent unauthorized access to the function.
(Edit, accepted):
Sadly, I can accept only one solution, so I subjectively picked the one that requires less work and provide much flexibility.
To future readers, Preet Kukreti (& texasbruce in comment) and Shmuel H. (& A.S.H is comment) has also provided good solutions that worth reading.
I think that the best way is not to include Util.h in a public header at all.
To do that, #include "Util.h" only in the implementation cpp file:
Lib.cpp:
#include "Util.h"
void A::publicFunction()
{
Util::calculate();
}
By doing that, you make sure that changing Util.h would make a difference only in your library files and not in the library's users.
The problem with this approach is that would not be able to use Util in your public headers (A.h, B.h). forward-declaration might be a partial solution for this problem:
// Forward declare Util:
class Util;
class A {
private:
// OK;
Util *mUtil;
// ill-formed: Util is an incomplete type
Util mUtil;
}
One possible solution would be to shove Util into a namespace, and typedef it inside the B and C classes:
namespace util_namespace {
class Util{
public:
static void calculate(); //implementation in Util.cpp
};
};
class B {
typedef util_namespace::Util Util;
public:
void foo()
{
Util::calculate(); // Works
}
};
class C {
typedef util_namespace::Util Util;
public:
void foo()
{
Util::calculate(); // Works
}
};
class D {
public:
void foo()
{
Util::calculate(); // This will fail.
}
};
If the Util class is implemented in util.cpp, this would require wrapping it inside a namespace util_namespace { ... }. As far as B and C are concerned, their implementation can refer to a class named Util, and nobody would be the wiser. Without the enabling typedef, D will not find a class by that name.
One way to do this is by friending a single intermediary class whose sole purpose is to provide an access interface to the underlying functionality. This requires a bit of boilerplate. Then A and B are subclasses and hence are able to use the access interface, but not anything directly in Utils:
class Util
{
private:
// private everything.
static int utilFunc1(int arg) { return arg + 1; }
static int utilFunc2(int arg) { return arg + 2; }
friend class UtilAccess;
};
class UtilAccess
{
protected:
int doUtilFunc1(int arg) { return Util::utilFunc1(arg); }
int doUtilFunc2(int arg) { return Util::utilFunc2(arg); }
};
class A : private UtilAccess
{
public:
int doA(int arg) { return doUtilFunc1(arg); }
};
class B : private UtilAccess
{
public:
int doB(int arg) { return doUtilFunc2(arg); }
};
int main()
{
A a;
const int x = a.doA(0); // 1
B b;
const int y = b.doB(0); // 2
return 0;
}
Neither A or B have access to Util directly. Client code cannot call UtilAccess members via A or B instances either. Adding an extra class C that uses the current Util functionality will not require modification to the Util or UtilAccess code.
It means that you have tighter control of Util (especially if it is stateful), keeping the code easier to reason about since all access is via a prescribed interface, instead of giving direct/accidental access to anonymous code (e.g. A and B).
This requires boilerplate and doesn't automatically propagate changes from Util, however it is a safer pattern than direct friendship.
If you do not want to have to subclass, and you are happy to have UtilAccess change for every using class, you could make the following modifications:
class UtilAccess
{
protected:
static int doUtilFunc1(int arg) { return Util::utilFunc1(arg); }
static int doUtilFunc2(int arg) { return Util::utilFunc2(arg); }
friend class A;
friend class B;
};
class A
{
public:
int doA(int arg) { return UtilAccess::doUtilFunc1(arg); }
};
class B
{
public:
int doB(int arg) { return UtilAccess::doUtilFunc2(arg); }
};
There are also some related solutions (for tighter access control to parts of a class), one called Attorney-Client and the other called PassKey, both are discussed in this answer: clean C++ granular friend equivalent? (Answer: Attorney-Client Idiom) . In retrospect, I think the solution I have presented is a variation of the Attorney-Client idiom.
In my class I have the need to keep a pointer to a structure which is defined in a library I use to implement it. Since this library is only used within the implementation file I would like to avoid including it in the header directly. At the same time I want to avoid polluting the namespace. Thus I would like to do:
/* HEADER */
class Foo {
private:
struct ImplementationDetail;
ImplementationDetail * p;
};
/* SOURCE */
#include <Library.h>
using Foo::ImplementationDetail = Library::SomeStruct;
But this doesn't work, and I'm currently falling back on PIMPL:
/* HEADER */
class Foo {
private:
struct ImplementationDetail;
ImplementationDetail * p_;
};
/* SOURCE */
#include <Library.h>
struct ImplementationDetail {
Library::SomeStruct * realp_;
}
Is there a way to avoid the double dereference? Is the reason for my non-working first solution due to unknown pointer sizes?
// Header
class Foo {
private:
struct ImplementationDetail;
ImplementationDetail * p;
};
// Source
#include <Library.h>
struct Foo::ImplementationDetail :public Library::SomeStruct {
// ....
};
and allocating/deallocating/dereferencing the pointer in this source file only should work just fine.
This is an incorrect declaration:
using Foo::ImplementationDetail = Library::SomeStruct;
using doesn't work this way. In C++11 using cannot create an alias for a name in one namespace to a name in another namespace. In C++03, all using does is bring some other namespace in to global visibility in the current translation unit. It's not used to create aliases in C++03, as you seem to want to do here.
pimpl is the de-facto method for doing what you're trying to do, but in your header file instead of trying to use a ImplementationDetail*, I would use a simple void*. Using a void* in this manner is guaranteed to be correct according to the Standard:
class Foo {
private:
void * pImpl;
Use static_cast2 to go from a void* to your actual type:
void Foo::Bar()
{
Library::SomeStruct* thingy = static_cast <Library::SomeStruct*> (pImpl);
// ...
}
You can avoid using the void* in a conformant way by forward-declaring your library type:
namespace Library
{
struct SomeStruct;
};
class Foo
{
private:
Library::SomeStruct* pStruct;
};
And then no ugly cast is needed in the implementation.
2 Use static_cast : Or reinterpret_cast
The reason you can't take your first approach is that in the header you tell the compiler "I'm declaring a nested class within Foo and it's called ImplementationDetail". Then you proceed to say "wait wait, it's NOT a new class, it's an alias to this other thing entirely" and understandably the compiler gets confused.
Have you tried just forward declaring the library's implementation and using that instead of trying to create an alias?
In your first code you declared the nested type ImplementationDetail to be a struct which will be define inside Foo. Trying to alias it can't work because that would be a type defined elsewhere and, actually, you private structure isn't accessible from outside the class. Wrapping a pointer to another object inside seems unecessary: you could instead either embed the Library::SomeStruct by value or have your ImplementationDetail derive from Library::SomeStruct:
struct ImplementationDetail
: Library::SomeStruct {
using Library::SomeStruct::SomeStruct;
};
(the using declaration is just used to inherit all the constructors from Library::SomeStruct).
I think this is not possible without casting.
Basically there are two ways to do it:
1) Define p_ as void* and cast it in every function that uses it.
/* HEADER */
class Foo {
private:
void* p;
};
/* SOURCE */
#include <Library.h>
void Foo::AnyFunc()
{
Library::SomeStruct* pImpl = reinterpret_cast<Library::SomeStruct*>(p);
...
}
2) Create a "shadowing"-class of your class (in the .cpp-file) with all members cloned and p_ defined as Library::SomeStruct. Then cast the this-pointer to this shadowing class. This is of course a quite insecure and dirty hack which I don't recommend...
/* HEADER */
class Foo {
private:
void* p;
};
/* SOURCE */
#include <Library.h>
class FooImpl
{
public:
void AnyFunc() { p->DoSomething(); }
private:
Library::SomeStruct* p;
}
void Foo::AnyFunc()
{
FooImpl* pImpl = reinterpret_cast<FooImpl*>(this);
pImpl->AnyFunc();
}
This exploits memory structure and is therefore quite fragile (all members need to be in the same order and when you add or remove members, you need to update ShadowFoo, too). I mentioned this just for completeness.
3) This brings us to yet another, but more simple way: create the implementation in the source file and initialize it in the constructor with the void*-pointer:
/* HEADER */
class Foo {
private:
void* p;
};
/* SOURCE */
#include <Library.h>
class FooImpl
{
public:
FooImpl(void* pSomeStruct)
{
p = reinterpret_cast<Library::SomeStruct*>(pSomeStruct);
}
void AnyFunc() { p->DoSomething(); }
private:
Library::SomeStruct* p;
}
void Foo::AnyFunc()
{
FooImpl impl = FooImpl(p);
impl.AnyFunc();
}
I am porting code from Java to c++ and I'd like to replicate some anonymous functionalities.
In file A.h I have :
class A
{
private:
int a;
class AnonClass;
friend class AnonClass;
};
In file A.cpp I have :
namespace
{
class AnonClass
{
public:
AnonClass(A* parent)
{
parent->a = 0; // This doesn't work, a is not accessible
}
}
}
Is it possible to friend a class in an anonymous namespace in C++?
In Java you can declare anonymous classes so it would be very similar. Also it would not expose AnonClass to clients of A.h
Less known alternative is to make class Anon a member class of A. Inside class A you only need a line class Anon; -- no real code, no friend declaration. Note it goes within class A, almost as in Java. In the .cpp file you write all the details about Anon but you put it not in anonymous namespace but withinA::
class A::Anon { ..... };
You can split declaration and implementation of A::Anon, as usual, just remeber always add A:: to Anon.
The class Anon is a member of A and as such gets access to all other members of A. Yet it remains unknown to clients of A and does not clutter global namespace.
As far as I can see you can not. The reasons:
The “anonymous” namespace is accessible only within the file you created it in.
You have to define whole AnonClass class and it's functions in one namespace, i.e. in one place in the program.
Class A has to be defined before AnonClass constructor.
AnonClass has to be at least declared before class A.
So you see, you can't break AnonClass definition on two parts. And you can't define it both before and after A class.
The only option - put class A into the same anonymous namespace. This code works:
namespace
{
class A
{
public:
A():a(0){};
private:
int a;
friend class AnonClass;
};
class AnonClass
{
public:
AnonClass(A* parent);
};
AnonClass::AnonClass(A* parent)
{
parent->a = 0;
};
}
int main() {
A a;
return 0;
}
I hope this helps.
Is it possible to use a class defined in an anonymous namespace as a parameter in a private member function? I haven’t found a way to forward declare AnonymousHelperClass in the header.
// C.h
class C
{
// ...
private:
void Boing(AnonymousHelperClass &helper);
};
.
// C.cpp
namespace
{
class AnonymousHelperClass
{
// . . .
};
}
C::Boing(AnonymousHelperClass &helper)
{
// ...
}
No, because there is no way to name the type in the header file.
However, you could turn the private member function into a template:
// C.h
class C
{
public:
void Foo();
private:
template <typename TAnonymousHelper>
void Boing(TAnonymousHelper&);
};
Then define it in the source file and use it with the AnonymousHelperClass:
// C.cpp
#include "C.h"
namespace
{
class AnonymousHelperClass { };
}
template <typename TAnonymousHelper>
void C::Boing(TAnonymousHelper& x) { }
void C::Foo()
{
AnonymousHelperClass x;
Boing(x);
}
Though really, it's probably easier just to rework your logic such that the private member function can be a namespace-scope function in the .cpp file.
No, because unnamed namespaces (that's what they're actually called) are defined like this in the C++ standard:
7.3.1.1 Unnamed namespaces [namespace.unnamed]
1. An unnamed-namespace-definition behaves as if it were replaced by
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
where all occurrences of unique in a translation unit are replaced by
the same identifier and this identifier differs from all other
identifiers in the entire program.
So with your class it's equivalent to:
namespace SomeUniqueNameGeneratedByTheCompiler {}
using namespace SomeUniqueNameGeneratedByTheCompiler;
namespace SomeUniqueNameGeneratedByTheCompiler
{
class AnonymousHelperClass
{
// . . .
};
}
So the full qualification of the AnonymousHelperClass class is ::SomeUniqueNameGeneratedByTheCompiler::AnonymousHelperClass, not ::AnonymousHelperClass. So even if you did this:
class AnonymousHelperClass; // Forward declaration
class C
{
// ...
private:
void Boing(AnonymousHelperClass &helper);
};
That forward declaration refers to a different AnonymousHelperClass. You could put the forward declaration in the SomeUniqueNameGeneratedByTheCompiler namespace, but since only the compiler knows this name, it can't be done.