Hiding a C++ class in a header without using the unnamed namespace - c++

I am writing a C++ header in which I define a
class A {
// ...
};
that I would like to hide from the outside world (because it may change or even be removed in future versions of this header).
There is also a class B in the same header that has an object of class A as a member:
class B {
public:
// ...
private:
A a_;
};
What is a proper way of hiding class A from the outside world?
If I put the definition of A in an unnamed namespace, the compiler issues a warning, so I assume that, due to issues with internal linkage, I should do something else.

The right way to go about it in C++ is PIMPL idiom. Alternative solution is to put the class you want to hide into a nested namespace, which is usually called detail. But that will not make it totally private as users will still be exposed to its dependencies, and will be able to use it directly.

You could do an inner class:
class B
{
class A { /* ... */ };
A a_;
}

Document that this class is not part of the public API and should not be used.
In C++ you have to trusted programs that link with your library code because you have little other choice. C++ has limited "access control" features many of which can be bypassed or abused so you're better of treating your API clients with respect and building trust.
If you design your API to be easy to use correctly and hard to use unintentionally incorrectly then you will be helping your clients and it is hardly your fault if your clients abuse your interface.

An unnamed namespace is useless anyways, as it only protects agains multiple definitions. What you could do is either using the pImpl Idiom, as mentioned in other answers, or use a detail namespace. Works fine for Boost:
namespace detail{
class A{
// ...
};
}
class B{
public:
// ...
private
A a_;
};
Anyone messing with stuff in a detail namespace is asking for trouble. Or maybe obscure it even more
namespace _b_impl_detail{
// ...
};
Anyone who now touches anything inside should be shot in the foot. :)

Instead of class B holding an A object, have it hold an A* instead (or a shared_ptr<A>, or an unique_ptr<A>, etc.). This way class B only needs a forward declaration of class A and class A can be fully defined inside of class B's source file.

If A is an implementation detail of B, don't put its definition in the header at all. Instead:
class B {
...
class A * myA;
};
and then put the definition of A in the B implementation (i.e. .cpp) file.

I'd like to add a small increment over https://stackoverflow.com/a/5780976/1525238 that helped me better solve my peculiar use case, namely where the "main" class is a template and the "helper/inner" class also has to be a template1.
I used a nested namespace called detail, made all "helper" content private and made the "main" class a friend of the "helper" class:
template<__MAIN_TEMPLATE_PARAMS__> class Main;
namespace detail {
template<__HELPER_TEMPLATE_PARAMS__> class Helper {
/* All Main templates are friends */
template<__MAIN_TEMPLATE_PARAMS__> friend class Main;
/* Private stuff, not reachable from the outside */
static void privateThing(){
...
}
};
}
template<__MAIN_TEMPLATE_PARAMS__> class Main {
void usePrivateThing(){
detail::Helper<__DESIRED_HELPER_TEMPLATE_PARAMS__>::privateThing();
}
};
The private stuff is static above only to make the code shorter. They may very well be tied to the Helper instance.
In retrospect, there could certainly be more elegant solutions involving less black magic, but it highly depends on the specific application. I still find the above a legit, nice use case for a friend class.
1 This is because I needed to use a template helper function that required a partial specialization, which is not allowed yet in c++, for no particular reason but is technically possible with a wrapper class. Partial specialization is omitted from the above for simplicity.

Related

Should I totally hide the internal class in my C++ header file when designing my SDK?

I am designing a SDK written in C++.
I have a question: could or should I totally hide the internal class in my public C++ header file?
The code snippets are like the following (in the header file MyPublicClass.h):
namespace PublicNamespace
{
namespace InternalNamespace
{
class MyInternalClass;
}
class MyPublicClass
{
public:
void SomeMemberFunc();
...
private:
std::shared_ptr<InternalNamespace::MyInternalClass> mImpl;
}
}
Per the C++ PImpl design pattern (and also many other materials from Google), it is OK to put the InternalNamespace::MyInternalClass into the public header.
My thought is: it looks unnecessary to let the external users know the internal namespace InternalNamespace, and also the class MyInternalClass. So I want to use void to replace the type InternalNamespace::MyInternalClass.
That's to say, for my case, I use std::shared_ptr<void> as the type of the data member mImpl, and in the .cpp file, use std::static_pointer_cast<InternalNamespace::MyInternalClass>(mImpl) to convert it to the actual class.
(Yeah, I know there is a little cost with this conversion but please ignore it).
Is this design correct or proper? Thanks all.
Don't use void or void * unless there is absolutely no alternative -- using void-pointers prevents the compiler from catching mistakes at compile-time, and leads to pain and suffering.
Using a clearly-labelled InternalNamespace should be good enough (assuming the programmers using your API aren't deliberately looking for trouble -- and if they are, there are plenty of other ways for them to find it anyway), although if you wanted to hide MyInternalClass entirely from calling code, you could instead make it an inner-class of MyPublicClass, i.e. something like this:
namespace PublicNamespace
{
class MyPublicClass
{
public:
void SomeMemberFunc();
...
private:
class MyInternalClass
{
[...]
};
std::shared_ptr<MyInternalClass> mImpl;
}
}
Since it's declared in the private section of MyPublicClass, no calling code outside of MyPublicClass would be able to access it at all.

Why can't we define an anonymous class in place for inheritance?

class MyClass : SomeFeatureGeneratedByTemplate<MyClass>
Template offers much convenience to add a feature to our class just by inheriting a instantiated class template.
However, sometimes the feature may get too complicated to be implemented by template, where macro might be the only choice.
MACRO_TO_GENERATE_COMPLICATED_FEATURE(MyClass)
/* Might be expanded to
#ifndef MYCLASS_FEATURE_CLASS
#define MYCLASS_FEATURE_CLASS
class MyClassFeature { ... };
#endif
*/
class MyClass : MyClassFeature
I wonder if the following syntax would simplify this:
allow to define a anonymous class just in place
class MyClass : class { ... }, class{ ... }
Therefore, the above code could be rewritten as:
class MyClass : MACRO_GEN_FEATURE(MyClass)
APPEND:
Q: Why don't I embed the code just inside class?
A:
1. This feature should be explicit and exposed to user. When they generating docs, derived class is easy to discover :class A: FEATURE1(A), FEATURE2(A) while embedded macro isn't. Although an empty class could be derived to achieve our goal(e.g class A: FEATURE1(A)//just derive predefined struct FEATURE1_EMPTY{};), apparently it is not a perfect solution.
Sometimes we even needn't to get any member from the class generated by macro, but that class has to include member to provide some function(e.g static_assert with some helper class templates).
Complete specialization of a nested class template is not allowed, which prevents me from using nested class to avoid namespace conflicts mentioned in 2).
I know that this is illegal right now, but why is this not allowed in C++ standard?
Because neither Bjarne (in the 1980s) nor anybody on the ISO committee (1990s—now) saw a need for this. I've never seen a need for it until this macro hackery today.
Here's how a language is developed:
Start with nothing
Feature is needed? Add it!
Here's how a language is not developed:
Start with every possible feature, in an ∞-pages long standard
Feature not needed? Remove it!
class MyClass : class { /* CONTENT */ } {
// HERE
};
What ever you would put where CONTENT is, would be only used or even accessible from the class MyClass, so it can equally well be written where the HERE stands.
If you want to "organise" the contents of a single class, you could use "nested" classes to enhance encapsulation:
class Thing {
class SomeSubThing {} subthing;
};
Though whether this useful or even recommendable is highly depended of the actual case and probably highly subjective.

Class namespace?

Is it me or the implementation of object oriented paradigm in C++ is missing the concept of class namespace?
Here is an example of what I mean:
Document { Header {} Body {} Footer {} }
Document is an object that can have a header, body, and footer.
A straight forward way to address such object and its elements from external namespace is
Document
Document::Header
Document::Body
Document::Footer
Is there a way to achieve such naming structure in C++ without imposing a restriction on the definition of Document class?
1) namespace Document { ... }
This case requires an object class inside its own namespace and using Document::Document seems redundant and unintended.
2) namespace Document { class ... } typedef Document::Document document;
This case gives document and Document::{part}, which in case sensitive language may seem weird and unrelated.
3) class Document { class ... };
This case requires including Document header in definition of every nested class and doesn't allow to make the final object be a derivative of its parts, since they are defined within its own scope.
4) class document { class ... }; class Document : public document {}
This case is close to what is intended but costs an extra class and inheritance.
!) Ideally, what I'd like to have is
namespace class Document {
class Header;
class Body;
class Footer;
class Document; // linked with the parent namespace as with its own name space
}
Document doc; // ok, resolves Document as a class
Document::{Part} docPart; // ok, resolves Document as namespace
.) Is there any other reasonable way to achieve what is intended without unreasonable extra cost?
I'm also not exactly sure why such trivial things are not a standard way to do it. :/ Any specific reason?
--- clarification ---
To address some of the raised questions,
"What is it useful for?" 1) Plain language 2) Transparent mapping from a language construct to an object's abstract model and vice versa.
"Why would one want to derive an object from its parts?" Not every entity introduced by an object has to be its part. It can be its essence, for example. E.g.:
Document { Skeleton{} Parts { Header {} Body {} Footer {} } }
--- abstract framework ---
Think of an object as a module whose definition may use external symbols and introduce some of its own along with the definition of its own logical entity, to which they should remain related since it introduces them.
--- point ---
The whole module is a definition of an object. It would be nice to be able to use it as such without any additional linguistic ridicules.
=== resolution ===
Thank you for your feedback.
Until there is a way in C++ to link a namespace name to a class, I guess I'll use the
ObjectName { ... Object {} } -> ObjectName::Object, ObjectName::Part
construct in such cases. It may be not as short as I'd like to, but at least transparent enough, with no extra cost, and can be used with forward declarations.
Your third option - using nested class declarations / definitions, will get you the ideal scope resolution as you want (though it will not involve a single namespace).
class Document
{
public:
class Header
{
// Header class declaration here
};
class Body
{
// Body class declaration here
};
class Footer
{
// Footer class declaration here
};
// Document declaration here.
};
Your concerns with that option are:
Requires including Document header in definition of every nested class
Yes - the nested classes are inextricably linked to the surrounding class, their implementations will depend on the definition of the surrounding class because it contains the definitions of the nested classes. This is unavoidable.
Dpesn't allow to make the final object be a derivative of its parts, since they are defined within its own scope.
What you are trying to do seems to make very little logical sense - you are trying to define something based on its own parts, which is a circular definition. What are you trying to achieve by deriving Document from Header, Body or Footer?
The final line of your question suggests that you find your desired functionality "trivial", but in my opinion and experience it is far from trivial. You seem to be conflating a namespace and a class because of syntactical similarities, but they are entirely different concepts. You have to separate the two in your mind, they have very little overlap besides some scoping effects and scope resolution syntax. Your "Document" must be either a namespace and a class. Pick one ;) (technically it's actually possible to have both a namespace Document and a class Document, but this is likely to be a source of confusion.
)
Your first case does exactly what you say you want. There's nothing redundant about Document::Document -- it refers to the Document class in the Document namespace. There might very well be a Document class in the XML namespace, and another one in the MyCompany namespace.
Your second case looks like an attempt to essentially defeat the purpose of using namespaces. If you don't want to use a namespace, don't -- just use the global (unspecified) namespace and risk collisions. If you only want to avoid the Document:: part in the code that's related to your Document class, add a using namespace Document directive in that code.
You just enclose the part classes within the Document class.
class Document {
public:
class Header;
class Body;
class Footer;
};
You can validly use this:
Document myDoc; // Type Document
Document::Header myHeader;
3) class Document { class ... };
This case requires including Document header in definition of every nested class and doesn't allow to make the final object be a derivative of its parts, since they are defined within its own scope.
No, this design is what makes the most sense. I don't understand what you think the difference would be between class and namespace class.
class Document
{
public:
class Header
{
};
Header m_header;
class Body
{
};
Body m_Body;
};
What's wrong with this design? You access the types via Document::Header. You access via instances like myDocument.m_header.
The only inherent oddness is that you can't name a type and member variable the same, but there are plenty of ways around that and it's a superficial restriction really.
Just because a Document object contains a Header object doesn’t mean that the Header class should be contained in the Document class. At least, that’s not usually done.
I would nest classes only in rare instances; namely, when the nested class is an implementation detail of the outer class, and isn’t exposed to the outside world (but even then it’s common to forego nesting).
This, by the way, is independent of C++: classes in general are rarely nested except to hide implementation details. Frameworks to model object relations as in your case wouldn’t normally use nesting. Instead, you might have something like this:
namespace Html {
class Document;
class Header;
class Body;
// …
}
C++ in particular uses flat namespace hierarchies but the above would equally apply to C# or Java.
Finally, to explicitly address your introductory question:
Is it me or the implementation of object oriented paradigm in C++ is missing the concept of class namespace?
C+ has this concept to the same extent as other modern OO languages: a class forms a namespace for the purpose of name lookup so you can achieve what you want. But for the reason mentioned above I don’t think it’s a particularly desirable goal.
It's not totally clear to me how much you want to expose the nested
classes, but if they are part of Document, they probably should be
nested classes. Your example of what you mean, at the start of your
code, is exactly how one would do this in C++:
class Document
{
public: // or not?
class Header
{
};
class Body
{
};
class Footer
{
};
};
About the only objection I can see is that implementation files only
concerned with Document::Header must include the entire Document
class definition, but I don't think this is a major problem; if
Document::Header really isn't independent, then it seems reasonable to
require this. With regards to your second objection to this solution:
you never want to make an object derive from its parts: a Document
hasA Header; it isn't an isA relationship.
If it does make sense for Header et al to be used separately, then the
best solution is to define them outside of the Document class, either
giving them more descriptive names (e.g. DocumentHeader) or wrapping
them in a special namespace (e.g. namespace DocumentParts). Depending
on their relationship with Document, it might make sense to use
typedef in Document so that they can be referred to as either
DocumentParts::Header or Document::Header.

Can I create functions without defining them in the header file?

Can I create a function inside a class without defining it in the header file of that class?
Why don't you try and see?
[˙ʇ,uɐɔ noʎ 'oᴎ]
Update: Just to reflect on the comments below, with the emphasis of the C++ language on smart compiling, the compiler needs to know the size of the class (thus requiring declaration of all member data) and the class interface (thus requiring all functions and types declaration).
If you want the flexibility of adding functions to the class without the need to change the class header then consider using the pimpl idiom. This will, however, cost you the extra dereference for each call or use of the function or data you added. There are various common reasons for implementing the pimpl:
to reduce compilation time, as this allows you to change the class without changing all the compilation units that depend on it (#include it)
to reduce coupling between a class' dependents and some often-changing implementation details of the class.
as Noah Roberts mentioned below the pimpl can also solve exception safety issues.
No. However, you can mimic such:
struct X
{
void f();
X();
~X();
private:
struct impl;
impl * pimpl;
};
// X.cpp
struct X::impl
{
void f()
{
private_function();
...
}
void private_function() { ...access private variables... }
};
//todo: constructor/destructor...
void X::f() { pimpl->f(); }
Short answer: No, you can't.
However, if you're trying to inject a private function into the class that will only be used in that class's implementation, you can create a function in an anonymous namespace within that class's .cpp file that takes an object of that type by reference or pointer.
Note that you won't be able to muck with the passed objects internal state directly (since there's no way for the class to declare friendship with that anonymous function), but if the function just aggregates operations from the public interface of the class it should work just fine.
No, you can't. It wouldn't make much sense anyway. How should users of your class that include the header file know about those functions and use them?
I have no idea what You are trying to do, but I have a strange gut feeling, that Pointer To Implementation (pImpl) idiom might be helpful. If you want to add a public method in a cpp file and that method is not declared in the class definition in a header, You can't do that and it doesn't make sense.

Pros and cons of using nested C++ classes and enumerations?

What are the pros and cons of using nested public C++ classes and enumerations? For example, suppose you have a class called printer, and this class also stores information on output trays, you could have:
class printer
{
public:
std::string name_;
enum TYPE
{
TYPE_LOCAL,
TYPE_NETWORK,
};
class output_tray
{
...
};
...
};
printer prn;
printer::TYPE type;
printer::output_tray tray;
Alternatively:
class printer
{
public:
std::string name_;
...
};
enum PRINTER_TYPE
{
PRINTER_TYPE_LOCAL,
PRINTER_TYPE_NETWORK,
};
class output_tray
{
...
};
printer prn;
PRINTER_TYPE type;
output_tray tray;
I can see the benefits of nesting private enums/classes, but when it comes to public ones, the office is split - it seems to be more of a style choice.
So, which do you prefer and why?
Nested classes
There are several side effects to classes nested inside classes that I usually consider flaws (if not pure antipatterns).
Let's imagine the following code :
class A
{
public :
class B { /* etc. */ } ;
// etc.
} ;
Or even:
class A
{
public :
class B ;
// etc.
} ;
class A::B
{
public :
// etc.
} ;
So:
Privilegied Access: A::B has privilegied access to all members of A (methods, variables, symbols, etc.), which weakens encapsulation
A's scope is candidate for symbol lookup: code from inside B will see all symbols from A as possible candidates for a symbol lookup, which can confuse the code
forward-declaration: There is no way to forward-declare A::B without giving a full declaration of A
Extensibility: It is impossible to add another class A::C unless you are owner of A
Code verbosity: putting classes into classes only makes headers larger. You can still separate this into multiple declarations, but there's no way to use namespace-like aliases, imports or usings.
As a conclusion, unless exceptions (e.g. the nested class is an intimate part of the nesting class... And even then...), I see no point in nested classes in normal code, as the flaws outweights by magnitudes the perceived advantages.
Furthermore, it smells as a clumsy attempt to simulate namespacing without using C++ namespaces.
On the pro-side, you isolate this code, and if private, make it unusable but from the "outside" class...
Nested enums
Pros: Everything.
Con: Nothing.
The fact is enum items will pollute the global scope:
// collision
enum Value { empty = 7, undefined, defined } ;
enum Glass { empty = 42, half, full } ;
// empty is from Value or Glass?
Ony by putting each enum in a different namespace/class will enable you to avoid this collision:
namespace Value { enum type { empty = 7, undefined, defined } ; }
namespace Glass { enum type { empty = 42, half, full } ; }
// Value::type e = Value::empty ;
// Glass::type f = Glass::empty ;
Note that C++0x defined the class enum:
enum class Value { empty, undefined, defined } ;
enum class Glass { empty, half, full } ;
// Value e = Value::empty ;
// Glass f = Glass::empty ;
exactly for this kind of problems.
One con that can become a big deal for large projects is that it is impossible to make a forward declaration for nested classes or enums.
If you're never going to be using the dependent class for anything but working with the independent class's implementations, nested classes are fine, in my opinion.
It's when you want to be using the "internal" class as an object in its own right that things can start getting a little manky and you have to start writing extractor/inserter routines. Not a pretty situation.
It seems like you should be using namespaces instead of classes to group like things that are related to each other in this way. One con that I could see in doing nested classes is you end up with a really large source file that could be hard to grok when you are searching for a section.
There are no pros and cons per se of using nested public C++ classes. There are only facts. Those facts are mandated by the C++ standard. Whether a fact about nested public C++ classes is a pro or a con depends on the particular problem that you are trying to solve. The example you have given does not allow a judgement about whether nested classes are appropriate or not.
One fact about nested classes is, that they have privileged access to all members of the class that they belong to. This is a con, if the nested classes does not need such access. But if the nested class does not need such access, then it should not have been declared as a nested class. There are situations, when a class A wants to grant privileged access to certain other classes B. There are three solutions to this problem
Make B a friend of A
Make B a nested class of A
Make the methods and attributes, that B needs, public members of A.
In this situation, it's #3 that violates encapsulation, because A has control over his friends and over his nested classes, but not over classes that call his public methods or access his public attributes.
Another fact about nested classes is, that it is impossible to add another class A::C as a nested class of A unless you are owner of A. However, this is perfectly reasonable, because nested classes have privileged access. If it were possible to add A::C as a nested class of A, then A::C could trick A into granting access to privileged information; and that yould violate encapsulation. It's basically the same as with the friend declaration: the friend declaration does not grant you any special privileges, that your friend is hiding from others; it allows your friends to access information that you are hiding from your non-friends. In C++, calling someone a friend is an altruistic act, not an egoistic one. The same holds for allowing a class to be a nested class.
Som other facts about nested public classes:
A's scope is candidate for symbol lookup of B: If you don't want this, make B a friend of A instead of a nested class. However, there are cases where you want exactly this kind of symbol lookup.
A::B cannot be forward-declared: A and A::B are tightly coupled. Being able to use A::B without knowing A would only hide this fact.
To summarize this: if the tool does not fit your needs, don't blame the tool; blame yourself for using the tool; others might have different problems, for which the tool is perfect.
paercebal said everything I would say about nested enums.
WRT nested classes, my common and almost sole use case for them is when I have a class which is manipulating a specific type of resource, and I need a data class which represents something specific to that resource. In your case, output_tray might be a good example, but I don't generally use nested classes if the class is going to have any methods which are going to be called from outside the containing class, or is more than primarily a data class. I generally also don't nest data classes unless the contained class is not ever directly referenced outside the containing class.
So, for example, if I had a printer_manipulator class, it might have a contained class for printer manipulation errors, but printer itself would be a non-contained class.
Hope this helps. :)
Remember that you can always promote a nested class to a top-level one later, but you may not be able to do the opposite without breaking existing code. Therefore, my advice would be make it a nested class first, and if it starts to become a problem, make it a top-level class in the next version.
For me a big con to having it outside is that it becomes part of the global namespace. If the enum or related class only really applies to the class that it's in, then it makes sense. So in the printer case, everything that includes the printer will know about having full access to the enum PRINTER_TYPE, where it doesn't really need to know about it. I can't say i've ever used an internal class, but for an enum, this seems more logical to keep it inside. As another poster has pointed out, it's also a good idea to to use namespaces to group similar items, since clogging the global namespace can really be a bad thing. I have previously worked on projects which are massive and just bringing up an auto complete list on the global namespace takes 20 minutes. In my opinion nested enums and namespaced classes/structs are probably the cleanest approach.
I agree with the posts advocating for embedding your enum in a class but there are cases where it makes more sense to not do that (but please, at least put it in a namespace). If multiple classes are utilizing an enum defined within a different class, then those classes are directly dependent on that other concrete class (that owns the enum). That surely represents a design flaw since that class will be responsible for that enum as well as other responsibilities.
So, yeah, embed the enum in a class if other code only uses that enum to interface directly with that concrete class. Otherwise, find a better place to keep the enum such as a namespace.
If you put the enum into a class or a namespace, intellisense will be able to give you guidance when you're trying to remember the enum names. A small thing for sure, but sometimes the small things matter.
Visual Studio 2008 does not seem to be able to provide intellisense for nested classes, so I have switched to the PIMPL idiom in most cases where I used to have a nested class. I always put enums either in the class if it is used only by that class, or outside the class in the same namespace as the class when more than one class uses the enum.
I can see a con for nested classes, that one may better use generic programming.
If the little class is defined outside the big one, you can make the big class a class template and use any "little" class you may need in the future with the big class.
Generic programming is a powerful tool, and, IMHO, we should keep it in mind when developing extensible programs. Strange, that no one has mentioned this point.
Only problem with nested classes that I bumped into yet was that C++ does not let us refer to the object of the enclosing class, in the nested class functions. We cannot say "Enclosing::this"
(But maybe there's a way?)