Archived

This topic is now archived and is closed to further replies.

unnamed namespaces

This topic is 5045 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello, I have been reading up on unnamed namespaces in the context of hiding classes as mentionned by the GOF Facade pattern description. I was hoping someone could shed some light on this. I would like the following classes where Facade has access to Alpha and Beta which are otherwise hidden. class Alpha { Beta *b; // and methods which call b methods }; class Beta { Alpha *a; // and methods which use a methods }; class Facade { // various manipulations of Alpha and Beta objects }; However I would like to be able to seperate these classes into seperate files (as in the case of say a compiler with a facade, the subsystem classes are numerous and large and keeping this in one file would be crazy). Is this at all feasible with unnamed namespaces as the GOF book describes? My major problem is the organisation of the code in headers and source files. On this front I'm totally lost! NB: Yes I know I could always do this with private constructors and friend classes but I would like to see a namespace version in action. Any help would be greatly appreciated. Many Thanks Anthony. [edited by - TonyFish on February 20, 2004 9:00:14 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Puzzler183
You can''t do what you did above ever. It results in an infinite chain of a''s and b''s. I don''t exactly know what you are trying to do, but I know that is horribly wrong.



i could be mistaken but why is that? they''re not referring to the same instances .. i bet this was just an example anyhow lol

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
i could be mistaken but why is that?
An Alpha contains a Beta, which contains an Alpha, which contains a Beta, which contains an Alpha, which contains a Beta, which contains an Alpha, which contains a Beta...

Which eventually explodes your compiler and causes smoke to come out of your monitor (no, not really).

Share this post


Link to post
Share on other sites
Actually, it contains a pointer to an Alpha and a Beta. As long as he would forward declare the classes, I can't see why the compiler would choke.

I may be missing something here, but Im pretty sure Ive done stuff like make a Map class contain a Engine pointer, and the Engine class contain a Map pointer

[EDIT]
As for the smoke coming out of the monitor, yeah, Ive had that before! Stupid monitor "blew up" in my face

[edited by - porthios on February 20, 2004 9:22:57 PM]

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
If you dont care about type safety, you could cast or uncast into or out of a void* instead of member Alpha* or Beta*

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:
Original post by Oluseyi
An Alpha contains a Beta, which contains an Alpha, which contains a Beta, which contains an Alpha, which contains a Beta, which contains an Alpha, which contains a Beta...

Which eventually explodes your compiler and causes smoke to come out of your monitor (no, not really).


But they''re pointers...so that shouldn''t happen, should it?

Share this post


Link to post
Share on other sites
unnamed namespaces are like prefacing a globabl function with static - they are only available in the file where they are defined.

The only wasy to restrict access is to either declare them in the same file, and in an unnamed namespace, or you could do something like you suggested:


class AHelper
{
friend class Blah;
private:
//define A stuff here

};

Share this post


Link to post
Share on other sites
The facade pattern exposes a unified interface to a complex underlying structure. It doesn''t have any direct correlation to unnamed namespaces, rather one can use unnamed namedspaces to implement a particular functionality of the facade pattern ( hiding implementation, as unmamed namespaces are scoped to the source module.)

In your case of having a transparent interface to A or B dependeing upon some runtime conditional element and only exposing the facade interface, is reasonable. Don''t get confused wtih implementation vs intention. Unnamed name spaces are a convient manner to hide localized implemation details within the same soruce module without polluting global namespace, however it would be unwise to take this idea to the extreme of having anything more than a few helper classes and functions. Otherwise you might find yourself with source modules taking up 1000s of lines. Just break down your classes into logical modules, and use the standard C++ paradyimes of interface abstraction and encaspualtion to implement your facade.

Good Luck!

-ddn

Share this post


Link to post
Share on other sites
The problem with unnamed namespaces is that the unique identifier for the namespace is different in each translation unit. This means it is practically impossible to split the implementation of the classes declared in the unnamed namespace across multiple translation unit, and will no doubt give you linker errors. e.g.


//unnamed.hpp

...
namespace
{
class A{ public: void somefunc();};
}
...

//A.cpp

#include "unnamed.hpp"
void someuniqueidentifier::A::somefunc(){...}

//Facade.cpp

#include "unnamed.hpp"
#include "Facade.hpp"
void Facade::somefunc()
{
anotheruniqueidentifier::A instance;
instance.somefunc();
}



Since the unique identifier is different in each translation unit, you have ended up defining a class that belongs to a different namespace than you have used, and so you will get a linker error .

Only way you could solve this is by defining the unnamed namespace objects inside the unnamed namespace.


[edited by - Jingo on February 21, 2004 6:49:12 AM]

Share this post


Link to post
Share on other sites
Well I've solved it thus:


*all the relevant external headers*

namespace Compiler
{
class Facade;
namespace // _UNIQUE_

{
#define _HEADER_
#include "SubAlpha.hpp"
#include "SubBeta.hpp"
#undef _HEADER_
#define _SOURCE_
#include "SubAlpha.hpp"
#include "SubBeta.hpp"
#undef _SOURCE_
}
class Facade {…};
}


Where SubAlpha.hpp will look like this


#ifdef _HEADER_

class SubAlpha
{
friend class Facade;
friend class SubBeta;
public:
int Method(void);
private:
SubAlpha();
};

#endif
#ifdef _SOURCE_

int SubAlpha::Method(void) {…}

#endif


This works but if it is used to hide 99% of a large project results in a massive translation unit which will a. be slower to compile and more importantly b. require a re-compile of everything whenever anything is changed.

Of course if anyone can think of anything wrong with this or any way of improving it I'd love to hear.

Thanks

[edited by - TonyFish on February 21, 2004 5:42:27 PM]

Share this post


Link to post
Share on other sites