Using friends with base classes for Boost Parameter - c++

I'm using the Boost Parameter tutorial to create a named-parameter constructor for a playing card generator. The tutorial says to put the ArgumentPack into a base class, but I want to modify variables in the card generator class. I've thought about doing this:
class CGconstructor_base {
public:
template<class ArgumentPack>
CGconstructor_base(ArgumentPack const& args);/*tutorial says to put code
in this function */
friend CardGenerator;//so it can modify the variables of CardGenerator
}
class CardGenerator:public CGconstructor_base;
Is this legal or is there a better way to manipulate the private variables in CardGenerator and use Boost Parameter library?
OS: Windows XP Pro, Compilier: Visual C++ 2008 Express,Boost: 1.39.0

I think we need some cleanup.
the friend declaration seems ill-placed, from the comment you want CGconstructor_base to be able to access CardGenerator attributes: if this is so, then the friend declaration goes into CardGenerator (I say who I consider as my friends, you do not declare yourself as being someone I consider a friend).
Why do you need friend anyway ? It would be much better if as in the tutorial you used a structure and then stuffed the attributes into CGconstructor_base. This way you will be able to access them from CardGenerator naturally without this supplementary line. When you can do without the 'friend' keyword you should (usual caveat: if doing so does not increase the cost too much).
you want PRIVATE inheritance here, this is a detail implementation. Only use public inheritance (or protected even) when OTHER classes/methods will need to know use you 'as-a' base.
In a nutshell:
struct CGconstructor_base {
template<class ArgumentPack>
CGconstructor_base(ArgumentPack const& args);/*tutorial says to put code
in this function */
cg_type1 cg_attr1;
cg_type2 cg_attr2;
}; // don't forget this
class CardGenerator:private CGconstructor_base {};
I do wonder why 'inheritance' has been chosen by boost instead of (I think) cleaner composition. It is so much easier to abuse inheritance (and require Multiple-Inheritance)... I suppose it is worth a subject of its own though.

Related

Why is Microsoft using struct rather than class in new code?

So normally I wouldn't ask a question like this because it seems like it could be opinion based or start some sort of verbal war on coding practices, but I think there might be a technical reason here that I don't understand.
I was looking over the code in the header files for vcpkg (a library packing manager that Microsoft is creating and is "new" code) because reading code generally is a good way to learn things you didn't know.
The first thing I noticed was the use of using rather than typedef.
Snippet from 'https://github.com/microsoft/vcpkg/blob/master/toolsrc/include/vcpkg/parse.h'
template<class P>
using ParseExpected = ExpectedT<std::unique_ptr<P>, std::unique_ptr<ParseControlErrorInfo>>;
I haven't personally used using this way before and an answer from: What is the difference between 'typedef' and 'using' in C++11?. Essentially, using is the new way to do it, and the benefit is that it can use templates. So Microsoft had a good reason to use using instead of typedef.
Looking at 'https://github.com/microsoft/vcpkg/blob/master/toolsrc/include/vcpkg/commands.h' I noticed that they did not use any classes. Instead it was only namespaces with a function or so in them. ie:
namespace vcpkg::Commands
{
namespace BuildExternal
{
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
}
}
I'm guessing that part of this is that the calling syntax looks essentially just like a static member function in a class, so the code performs the same but maybe saves some overhead by being a namespace instead of a class. (If anyone has any ideas on this too that would be great.)
Now the main point of all this. Why is Microsoft using structs instead of classes in their namespaces?
Snippet from 'https://github.com/microsoft/vcpkg/blob/master/toolsrc/include/vcpkg/parse.h':
namespace vcpkg::Parse
{
/* ... Code I'm excluding for brevity ... */
struct ParagraphParser
{
ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {}
void required_field(const std::string& fieldname, std::string& out);
std::string optional_field(const std::string& fieldname) const;
std::unique_ptr<ParseControlErrorInfo> error_info(const std::string& name) const;
private:
RawParagraph&& fields;
std::vector<std::string> missing_fields;
};
}
Searching stackoverflow, I found an old question: Why Microsoft uses a struct for directX library instead of a class?
Which the answers were essentially, you don't have to declare things as public as default and a comment way at the bottom saying that it was old code.
If vcpkg was old code I would be completely satisfied, however, this is new code. Is it just some style they have that is a carry over (but using vs typedef isn't)? Or is it to save a line of code (public:)? Or is there some sort of overhead benefit? Or some other thing I haven't considered at all?
The only differences between struct and class are:
the default member access (public vs private) and
the default inheritance if you inherit from the type (public inheritance vs private inheritance).
The end result of 1 will be the same once the author has finished adding public:/private: to the type. 2 you can easily control yourself by being explicit when you inherit, rather than rely on the default. It's hardly a big deal and doesn't really matter.
As to why Microsoft uses struct rather than class in their code, you will have to ask some Microsoft people.
Regarding the free functions vs static functions, I don't think there is any overhead in this with classes (I haven't measured this at all, I would just think that most compiler would recognize that the class is basically just a namespace for the function). The thing is just: You don't need a class.
Using a class with only static functions is basically abusing the class as a namespace. So if you are only doing that, then be explicit about it and just use a namespace. Having a class there would only be confusing since you would think that maybe there could be some state here and just see that there is non when you see that the function in the class is static.
This is especially relevant if this is used a bit wrongly. Imagine someone instantiates a class A a with static member function f to call a.f(). It is no problem regarding performance, since the construction is a no-op and it will pretty much be equivalent to A::f(). But for the reader it seems like there is some kind of state involved and that is just confusing.
Regarding the other two: using is just superior to typedef throught being able to use templates and is (IMO) better readable. The struct vs class issue is just something over what has the better defaults, its not a big difference, but most often, what you want is what a struct does, so there is no reason to use a class.
To be (more) compatible with C
To avoid making everything public by using the public: keyword, since that all COM objects for example have only public member functions.

Policies interacting with one another in policy-based design

I'm trying to program a genetic algorithm for a project and am having difficulty keeping different functions separate. I've been reading up on policy-based design, and this seems like a solution to the problem, but I don't really understand how to implement it.
I've got an OptimizerHost, which inherits from a SelectionPolicy (to determine what solutions are evaluated) and a FitnessPolicy (to determine the fitness of any given solution). The problem is I can't figure out how the two policies can communicate with one another. The bulk of the algorithm is implemented in the SelectionPolicy, but it still needs to be able to check the fitness of its solutions. The only thing I can think of is to implement the SelectionPolicy algorithm in the OptimizerHost itself, so then it will inherit the things it needs from the FitnessPolicy. But that seems like its missing the point of using policies in the first place. Am I misunderstanding something?
I'm not very familiar with the Policy-Based design principles (sorry) but when I read your problem, I felt like you need something like pure virtual classes (as interfaces) to help you through it.
The thing is, you cannot use something from the other, if it's not previously declared: this is the basic rule. Thus, you need to use and virtual interface to say SelectPolicy that FitnessPolicy has some members to be used. Please follow the example, and change it accordingly to your algortihms-needs.
First: create the interfaces for the SelectionPolicy and the FitnessPolicy
template <class T> class FitnessPolicyBase
{
public:
virtual int Fitness(T fitnessSet); // assuming you have implemented the required classes etc. here - return value can be different of course
...
} // write your other FitnessPolicy stuff here
template <class T> class SelectionPolicyBase
{
public:
virtual T Selector(FitnessPolicyBase<Solution> evaluator, Set<T> selectionSet); // assuming such a set exists here
...
} // write your other selectionpolicy interface here
Now, since we made these classes pure virtual (they have nothing but virtual functions) we cannot use them but only inherit from them. This is precisely what we'll do: The SelectionPolicy class and the FitnessPolicy class will be inheriting from them, respectively:
class SelectionPolicy: public SelectionPolicyBase<Solution> // say, our solutions are of Solution Type...
{
public:
virtual Solution Selector(FitnessPolicyBase<Solution> evaluator, Set<Solution> selectionSet); // return your selected item in this function
...
}
class FitnessPolicy : public FitnessPolicy Base<Solution> // say, our solutions are of SolutionSet Type...
{
public:
virtual int Fitness(Solution set); // return the fitness score here
...
}
Now, our algortihm can run with two types of parameters: SolutionSetBase and FitnessSetBase. Did we really need the xxxBase types at all? Not actually, as long as we have the public interfaces of the SolutionPolicy and FitnessPolicy classes, we could use them; but using this way, we kinda seperated the `logic' from the problem.
Now, our Selection Policy algorithm can take references to the policy classes and then call the required function. Note here that, policy classes can call each others' classes as well. So this is a valid situation now:
virtual Solution SelectionPolicy::Selector(FitnessPolicyBase<Solution> evaluator, Set<T> selectionSet)
{
int score = evaluator.Fitness(selectionSet[0]); //assuming an array type indexing here. Change accordingly to your implementation and comparisons etc.
}
Now, in order for this to work, though, you must have initialized a FitnessPolicy object and pass it to this Selector. Due to upcasting and virtual functions, it will work properly.
Please forgive me if I've been overcomplicating things - I've been kinda afar from C++ lately (working on C# recently) thus might have mistaken the syntax an stuff, but logic should be the same anyway.

How does this code create an instance of a class which has only a private constructor?

I'm working on a sound library (with OpenAL), and taking inspiration from the interface provided by FMOD, you can see the interface at this link.
I've provided some concepts like: Sound, Channel and ChannelGroup, as you can see through FMOD interface, all of those classes have a private constructor and, for example, if you would create a Sound you mast use the function createSound() provided by the System class (the same if you would create a Channel or a ChannelGroup).
I'd like to provide a similar mechanism, but I don't understand how it work behind. For example, how can the function createSound() create a new istance of a Sound? The constructor is private and from the Sound interface there aren't any static methods or friendship. Are used some patterns?
EDIT: Just to make OP's question clear, s/he is not asking how to create a instance of class with private constructor, The question is in the link posted, how is instance of classes created which have private constructor and NO static methods or friend functions.
Thanks.
Hard to say without seeing the source code. Seems however that FMOD is 100% C with global variables and with a bad "OOP" C++ wrapper around it.
Given the absence of source code and a few of the bad tricks that are played in the .h files may be the code is compiled using a different header file and then just happens to work (even if it's clearly non-standard) with the compilers they are using.
My guess is that the real (unpublished) source code for the C++ wrapper is defining a static method or alternatively if everything is indeed just global then the object is not really even created and tricks are being played to fool C++ object system to think there is indeed an object. Apparently all dispatching is static so this (while not formally legal) can happen to work anyway with C++ implementations I know.
Whatever they did it's quite ugly and non-conforming from a C++ point of view.
They never create any instances! The factory function is right there in the header
/*
FMOD System factory functions.
*/
inline FMOD_RESULT System_Create(System **system)
{ return FMOD_System_Create((FMOD_SYSTEM **)system); }
The pointer you pass in to get a System object is immediately cast to a pointer to a C struct declared in the fmod.h header.
As it is a class without any data members who can tell the difference?
struct Foo {
enum Type {
ALPHA,
BETA_X,
BETA_Y
};
Type type () const;
static Foo alpha (int i) {return Foo (ALPHA, i);}
static Foo beta (int i) {return Foo (i<0 ? BETA_X : BETA_Y, i);}
private:
Foo (Type, int);
};
create_alpha could have been a free function declared friend but that's just polluting the namespace.
I'm afraid I can't access that link but another way could be a factory pattern. I'm guessing a bit, now.
It is the factory pattern - as their comment says.
/*
FMOD System factory functions.
*/
inline FMOD_RESULT System_Create(System **system) { return FMOD_System_Create((FMOD_SYSTEM **)system); }
It's difficult to say exactly what is happening as they don't publish the source for the FMOD_System_Create method.
The factory pattern is a mechanism for creating an object but the (sub)class produced depends on the parameters of the factory call. http://en.wikipedia.org/wiki/Factory_method_pattern

How should I order the members of a C++ class?

Is it better to have all the private members, then all the protected ones, then all the public ones? Or the reverse? Or should there be multiple private, protected and public labels so that the operations can be kept separate from the constructors and so on? What issues should I take into account when making this decision?
I put the public interface first, but I didn't always do this. I used to do things backwards to this, with private, then protected, then public. Looking back, it didn't make a lot of sense.
As a developer of a class, you'll likely be well acquainted with its "innards" but users of the class don't much care, or at least they shouldn't. They're mostly interested in what the class can do for them, right?
So I put the public first, and organize it typically by function/utility. I don't want them to have to wade through my interface to find all the methods related to X, I want them to see all that stuff together in an organized manner.
I never use multiple public/protected/private sections - too confusing to follow in my opinion.
Google favors this order: "Typedefs and Enums, Constants, Constructors, Destructor, Methods, including static methods, Data Members, including static data members."
Matthew Wilson (Safari subscription required) recommends the following order: "Construction, Operations, Attributes, Iteration, State, Implementation, Members, and my favorite, Not to be implemented."
They offer good reasons, and this kind of approach seems to be fairly standard, but whatever you do, be consistent about it.
Coding style is a source for surprisingly heated conversation, with that in mind I risk providing a different opinion:
Code should be written so it is most readable for humans. I complete agree with this statement that was given here several times.
The deviation is which roll are we taking about.
To help the user of the class understand how to use it, one should write and maintain proper documentation. A user should never be needing to read the source code to be able to use the class. If this is done (either manually or using in-source documentation tools) then the order in which public and private class members are defined in the source does not matter for the user.
However, for someone who needs to understand the code, during code review, pull request, or maintenance, the order matters a great deal - the rule is simple:
items should be defined before they are used
This is neither a compiler rule not is it a strictly public v.s. private rule, but common sense - human readability rule. We read code sequentially, and if we need "juggle" back and forth every time we see a class member used, but don't know its type for example, it adversely affects the readability of the code.
Making a division strictly on private v.s. public violates this rule because private class members will appear after they have been used in any public method.
It's my opinion, and I would wager a guess that most people would agree, that public methods should go first. One of the core principles of OO is that you shouldn't have to care about implementation. Just looking at the public methods should tell you everything you need to know to use the class.
As always, write your code for humans first. Consider the person who will be using your class and place the most important members/enums/typedefs/whatever to them at the top.
Usually this means that public members are at the top since that's what most consumers of your class are most interested in. Protected comes next followed by privates. Usually.
There are some exceptions.
Occasionally initialisation order is important and sometimes a private will need to be declared before a public. Sometimes it's more important for a class to be inherited and extended in which case the protected members may be placed higher up. And when hacking unit tests onto legacy code sometimes it's just easier to expose public methods - if I have to commit this near-sin I'll place these at the bottom of the class definition.
But they're relatively rare situations.
I find that most of the time "public, protected, private" is the most useful to consumers of your class. It's a decent basic rule to stick by.
But it's less about ordering by access and more about ordering by interest to the consumer.
I usually define first the interface (to be read), that is public, then protected, then private stuff. Now, in many cases I go a step forward and (if I can handle it) use the PIMPL pattern, fully hiding all the private stuff from the interface of the real class.
class Example1 {
public:
void publicOperation();
private:
void privateOperation1_();
void privateOperation2_();
Type1 data1_;
Type2 data2_;
};
// example 2 header:
class Example2 {
class Impl;
public:
void publicOperation();
private:
std::auto_ptr<Example2Impl> impl_;
};
// example2 cpp:
class Example2::Impl
{
public:
void privateOperation1();
void privateOperation2();
private: // or public if Example2 needs access, or private + friendship:
Type1 data1_;
Type2 data2_;
};
You can notice that I postfix private (and also protected) members with an underscore. The PIMPL version has an internal class for which the outside world does not even see the operations. This keeps the class interface completely clean: only real interface is exposed. No need to argue about order.
There is an associated cost during the class construction as a dynamically allocated object must be built. Also this works really well for classes that are not meant to be extended, but has some short comings with hierarchies. Protected methods must be part of the external class, so you cannot really push them into the internal class.
I tend to follow the POCO C++ Coding Style Guide.
i think it's all about readability.
Some people like to group them in a fixed order, so that whenever you open a class declaration, you quickly know where to look for e.g. the public data members.
In general, I feel that the most important things should come first. For 99.6% of all classes, roughly, that means the public methods, and especially the constructor. Then comes public data members, if any (remember: encapsulation is a good idea), followed by any protected and/or private methods and data members.
This is stuff that might be covered by the coding standards of large projects, it can be a good idea to check.
In our project, we don't order the members according to access, but by usage. And by that I mean, we order the members as they are used. If a public member uses a private member in the same class, that private member is usually located in front of the public member somewhere, as in the following (simplistic) example:
class Foo
{
private:
int bar;
public:
int GetBar() const
{
return bar;
}
};
Here, the member bar is placed before the member GetBar() because the former is used by the latter. This can result in multiple access sections, as in the following example:
class Foo
{
public:
typedef int bar_type;
private:
bar_type bar;
public:
bar_type GetBar() const
{
return bar;
}
};
The bar_type member is used by the bar member, see?
Why is this? I dunno, it seemed more natural that if you encounter a member somewhere in the implementation and you need more details about that (and IntelliSense is screwed up again) that you can find it somewhere above from where you're working.
In practice, it rarely matters. It's primarily a matter of personal preference.
It's very popular to put public methods first, ostensibly so that users of the class will be able to find them more easily. But headers should never be your primary source of documentation, so basing "best practices" around the idea that users will be looking at your headers seems to miss the mark for me.
It's more likely for people to be in your headers if they're modifying the class, in which case they should care about the private interface.
Whichever you choose, make your headers clean and easy to read. Being able to easily find whatever info I happen to be looking for, whether I'm a user of the class or a maintainer of the class, is the most important thing.
It is really helpful to the folks that will use your class to list the public interface first. It's the part they care about and can use. Protected and private can follow along after.
Within the public interface, it's convenient to group constructors, property accessors and mutators, and operators in distinct groups.
Note that (depending on your compiler and dynamic linker), you can retain compatibility with previous versions of a shared library by only adding to the end of the class (i.e. to the end of the interface), and not removing or changing anything else. (This is true for G++ and libtool, and the three part versioning scheme for GNU/Linux shared libraries reflects this.)
There's also the idea that you should order members of the class to avoid wasted space due to memory alignment; one strategy is to order members from smallest to largest size. I've never done this either in C++ or C though.
Overall, your public interface should come before anything, because that's the main/only thing that users of your classes should be interested in. (Of course, in reality that doesn't always hold, but it's a good start.)
Within that, member types and constants are best first, followed by construction operators, operations, and then member variables.
Put the private fields first.
With modern IDEs, people don't read the class to figure out what it's public interface is.
They just use intellisence (or a class browser) for that.
If someone is reading through the class definition, it's usually because they want to understand how it works.
In that case, knowing the fields helps the most. It tells you what the parts of the object are.
binary compatibility
There are a few concrete reasons for the ordering of class members.
These have to do with binary compatibility.
Binary compatibility mainly affects changes to system DLLs and device drivers.
If you're not interested in these, ignore this answer.
Public members must go before private members.
This is so you can mix and change private members without affecting the location of public data.
New public members must go last.
This again avoids affecting the position of existing public members.
The same ordering applies to vtable members.
Apart from this there's no reason to not to follow your own/your colleagues' preferences.
Depends entirely on your preference. There is no "the right way".
When doing C++ in my own pet projects I personally keep convention that I put access modifier before each member or method declaration.

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?)