I have a nested class in c++ which has to be public. But I need some of its methods visible to the outer world, and the rest visible only to the nesting class. That is:
class set {
public:
class iterator {
innerMethod();
public:
outerMethod();
}
}
I want to be able to write a method for set which uses innerMethod(). If I make it public, I can access it from outside as well, which is something that I definitely don't want. Is there a way to do it without doing the "friend class set" thing?
Thanks in advance!
There is NO GOOD WAY you can do this, without using friend keyword.
In the comment you said:
In the programming class I currently
take, using 'friend' was said to be
ill-advised and generally considered
"bad programming" for the most part,
unless there is really no other way
around it. So I try to avoid it as
much as possible.
friend breaks encapsulation, maybe that is the reason why your class teacher said it's bad-programming. But member-functions too break encapsulation, then why do you use them? Why not avoid them too? friend breaks encapsulation in the same way as do member-functions; so if you're comfortable using member-functions when they're needed, then you should be comfortable using friend also when they're needed. Both exist in C++ for a reason!
class set {
public:
class iterator
{
friend class set; //<---- this gives your class set to access to inner methods!
void innerMethod(){}
public:
void outerMethod(){}
};
iterator it;
void fun()
{
it.innerMethod();
it.outerMethod();
}
};
See this : How Non-Member Functions Improve Encapsulation
No, I don't think there are other non-hacky methods but using the friend-directive.
friend exists right for this kind of purpose, why would you avoid it?
Try asking: is there any way to add 2 numbers without adding them?
Sorry if I'm harsh, but friend class is for exactly that...
Yes there is.
I've been trying to advocate the method for a while now, the basic idea is to use a Key class.
While this does not actually remove the use of friend, it does reduce the set of exposed implementations details.
class set;
// 1. Define the Key class
class set_key: noncopyable { friend class set; set_key() {} ~set_key() {} };
class set
{
// 2. Define the iterator
class iterator
{
public:
void public_method();
void restricted_method(set_key&);
}; // class iterator
}; // class set
Now, restricted_method is public, so set does not need any special access to iterator. However the use of it is restricted to those able to pass a set_key instance... and conveniently only set may build such an object.
Note that set may actually pass a set_key object to someone else it trusts. It is a key in the traditional sense: if you give a key of your flat to someone, it may entrust it to another person. However because of the semantics of the key class (non copyable, only set may construct and destroy it) this is normally limited to the duration of the scope of the key object.
Note that a evil hack is always possible, namely *((set_key*)0). This scheme protects from Murphy, not Machiavelli (it's impossible in C++ anyway).
You can do something like this:
class set
{
public:
class iterator
{
protected:
iterator(){};
virtual ~iterator(){};
public:
//outer world methods...
};
private:
class privateIterator : public iterator
{
public:
privateIterator(){};
~privateIterator(){}
//inner methods;
};
public:
iterator* CreateIterator()
{
return new privateIterator();//this is used to be sure that you only create private iterator instances
}
};
I don't know if it's the right answer, but it does now uses friend key work and it hides some of the methods. The only problem is that you can't declare privateIterator and you always must use CreateIterator to create an instance...
Related
I would like to ask question regarding internal helper class in C++. What is the best way to structure this?
Let me clarify what do I mean by internal helper class by example.
// MyClass.h
class MyClass
{
int myData;
bool isSomething;
...
public:
void DoSomething();
};
// MyClass.cpp
// This is what I mean by internal helper function. Helper function that's only visible int the implementation file (.cpp) but requires access to the private members of the class.
static void DoSomethingInternal( MyClass *myClass )
{
// Access myClass private members
}
void MyClass::DoSomething()
{
...
DoSomethingInternal(this);
...
}
I know that declaring friend function can be a solution. However, it makes the class declaration ugly. In addition, for every new helper function, I have to add a friend function.
Is there an idiom/design pattern for this? I have been searching in the Internet, but didn't find any.
Thank you in advance. Your answers are greatly appreciated.
In my experience, a lot of dev teams have no problem with static local helper functions, it helps reduce header bloat, helps keep the formally exposed interface smaller, and so forth. It has the advantage of being lightweight, it has the disadvantage that it can lead to friend bloat/pollution if you are using lots of private members and no accessors.
But within the discussion community it is generally frowned upon in favor of the following.
Declaring helpers as private member functions.
This has the advantage of clearly associating fn _doThingsForFoo(Foo*) with Foo, and saving you from a lot of headaches exposing private members.
It has the downside of basically showing your underwear to everyone who needs to #include your header.
Using the Pimpl idiom.
You declare a second class, the "Private Implementation" (https://en.wikipedia.org/wiki/Opaque_pointer, Is the pImpl idiom really used in practice?) and you put all of the private stuff you don't want in the main header into that.
It has the advantage of allowing you to hide your stuff, it has the disadvantage of adding an extra pointer to feed, store and traverse (oh and free).
There are couple of ways to accomplish that.
Use a helper class/function in the .cpp file if the helper functions don't need access to the data directly. I would recommend this method ahead of the next method.
In the .cpp file:
// Create a namespace that is unique to the file
namespace MyClassNS
{
namespace HelperAPI
{
void DoSomethingInternal(MyClass* obj) { ... }
}
}
using namespace MyClassNS;
void MyClass::DoSomething()
{
...
//
HelperAPI::DoSomethingInternal(this);
...
}
Use the pimple idiom. When using this idiom, you can add any number of helper functions in the private data class without touching the public interface of the class.
The design pattern is simple: don't use helper classes. If a class should do something, let it do it itself.
As per the upvoted answer given by StenSoft, you should implement the methods inside the class. However, if that is not an option for some reason, then use helpers. If even that is not an option, then use reflection. If even that is not an option, then use a command listener inside your class. If even that is not an option, then watch a tutorial.
You can read these following sites for this purpose PIMPL, Opaque pointer. With this you only need to have one member variable and you can put all private things into the private class.
your header:
class PrivateClass;
class Class
{
public:
// ...
private:
PrivateClass* m_Private;
};
your source:
class PrivateClass
{
// ...
};
Class::Class
: m_Private( new PrivateClass )
{
// ...
}
UPDATE: I forgot to tell mention to delete the private member in the desctructor.
Class::~Class
{
delete m_Private;
// ...
}
// ...
In C++ is always better to keep data of a class as private members.
If a class has a vector as member is better to put it as a private or public member?
If I have a vector as private member I cannot easily access to the member function of the vector. So I have to design the class with a method for every function I need to access the vector methods?
Example given:
class MyClass{
private:
std::vector<int> _myints;
public:
get_SizeMyints(){return _myints.size();}
add_IntToMyints(int x){_myints.push_back(x));
};
or is better to keep the vector public and call MyClass._myints.push_back(x)?
---------------------edit--------------
and just for clarity for what is needed this question:
snake.h:
enum directions{UP, DOWN, RIGHT, LEFT, IN, OUT, FW, RW };
class Snake
{
private:
enum directions head_dir;
int cubes_taken;
float score;
struct_color snake_color;
V4 head_pos;
public:
std::vector<Polygon4> p_list; //the public vector which should be private...
Snake();
V4 get_head_pos();
Polygon4 create_cube(V4 point);
void initialize_snake();
void move(directions);
void set_head_dir(directions dir);
directions get_head_dir();
void sum_cubes_taken(int x);
int get_cube_taken();
void sum_score(float x);
float get_score();
void set_snake_color();
};
so now I know how to change the code.
btw... a question, if I need to copy the vector in an other class like this: GlBox.p_list = Snake.p_list (works if are private) what will be an efficent method if they where private?
Running a for cycle to copy the the elements and pusshing back them in the GLBox.p_list seems a bit inefficent to me (but may be just an impression) :(
If it doesn't matter if someone comes along and empties the vector or rearranges all it's elements, then make it public. If it matters, then yes, you should make it protected/private, and make public wrappers like you have. [Edit] Since you say "it's a snake", that means it'd be bad if someone came and removed or replaced bits. Ergo, you should make it protected or private. [/Edit]
You can simplify a lot of them:
MyClass {
private:
std::vector<int> _myints;
public:
const std::vector<int>& get_ints() const {return _myints;}
add_IntToMyints(int x){_myints.push_back(x));
};
That get_ints() function will allow someone to look at the vector all they want, but won't let them change anything. However, better practice is to encapsulate the vector entirely. This will allow you to replace the vector with a deque or list or something else later on. You can get the size with std::distance(myobj.ints_begin(), myobj.ints_end());
MyClass {
private:
std::vector<int> _myints;
public:
typedef std::vector<int>::const_iterator const_iterator;
const_iterator ints_begin() const {return _myints.begin();}
const_iterator ints_end() const {return _myints.end();}
add_IntToMyints(int x){_myints.push_back(x));
};
For good encapsulation, you should keep your vector private.
Your question is not very concrete, so here's an answer in the same spirit:
Generally, your classes should be designed to express a particular concept and functionality. They should not just hand through another member class. If you find yourself replicating all the interface functions of a member object, something is wrong.
Maybe sometimes you really just need a collection of other things. In that case, consider a plain old aggregate, or even a tuple. But if you're designing a proper class, make the interface meaningful to the task at hand, and hide the implementation. So the main question here is, why do you need to expose the vector itself? What is its role in the class? What does its emptiness signify in terms of the semantics of your class?
Find the appropriate idioms and ideas to design a minimal, modular interface for your class, and the question might just go away by itself.
(One more idea: If for example you have some range-based needs, consider exposing a template member function accepting a pair of iterators. That way you leverage the power of generic algorithms without depending on the choice of container.)
Normally, good coding practice is to keep your data members private or protected, and provide whatever public methods will be needed to access them. Not all the methods of (in this case) vector, just what will be useful for your application.
That depends on your class's purpose. If you're trying simply trying to wrap the vector and want to use it as a vector you could make an argument for making the vector public.
Generally speaking I would suggest making it private and providing an appropriate interface to manipulate the container. Additionally this lets you change the container under the hood if a different container would ever be more appropriate (as long as you don't tie your public interface to the container type).
Further as an aside, avoid names that begin with underscores as there are some such identifiers reserved for the implementation and it's safer to just avoid all of them rather than trying to remember the rules in all cases.
A point to realize is that making the std::vector private is only half of the story when it comes to good encapsulation. For example, if you have:
class MyClass {
public:
// Constructors, other member functions, etc.
int getIntAt(int index) const;
private:
std::vector<int> myInts_;
};
...then arguably, this is no better than just making myInts_ public. Either way, clients will write code using MyClass which is dependent on the fact that the underlying representation requires the use of a std::vector. This means that in the future, if you decide that a more efficient implementation would utilize a std::list instead:
class MyClass {
public:
// Constructors, other member functions, etc.
int getIntAt(int index) const; // whoops!
private:
std::list<int> myInts_;
};
...now you have a problem. Since you can't access into a std::list by index, you would either have to get rid of getIntAt, or implement getIntAt using a loop. Neither option is good; in the first case, you now have clients with code that doesn't compile. In the second case, you now have clients with code that just silently became less efficient.
This is the danger of exposing any public member functions which are specific to your choice of implementation. It's important to keep flexibility/future maintenance in mind when designing your class interface. There are a number of ways you could do this with your particular example; see Mooing Duck's answer for one such interface that exposes iterators.
Or, if you would like to maximize code readability, you could design the interface around what MyClass logically represents; in your case, a snake:
class MyClass {
public:
// Constructors, etc.
void addToHead(int value);
void addToTail(int value);
void removeFromHead();
void removeFromTail();
private:
// implementation details which the client shouldn't care about
};
This offers an abstraction of a snake object in your program, and the simplified interface gives you the flexibility to choose whatever implementation suits it best. And if the situation arises, you can always change that implementation without breaking client code.
Theoretically in Object Oriented Programming any attributes should be private and gain access to them via public methods such as Get() and Set().
I think you question is not complete, but what I understand from what you're trying to achieve you need to inherit from std::vector and extend its functionality, to both satisfy your fast access needs and not messing around with encapsulation. (Consider reading on "Inheritance" first from any C++ book, or other OO language)
Having said that, your code might look as following:
class MyClass : public std::vector<int>
{
//whatever else you need goes here
}
int main(void)
{
MyClass var;
var.push_back(3);
int size = var.size(); // size will be 1
}
Hope this answered your question
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
When should you use 'friend' in C++?
I have come to a stumbling block because of lack of documentation on friend classes. Most books just explain it briefly, e.g an excerpt from C++: the Complete Reference:
Friend Classes are seldom used. They are supported to allow certain special case situations to be handled.
And frankly, I have never seen a friend class in any good code made by an experienced C++ programmer. So , here is my list of problems.
Do Inherited Classes have the same friends as there base classes? e.g, if I declare class foo as a friend of class base, will class der (derived from base) also have foo as a friend?
What are the special case situations when a friend class should be used?
I am making a winapi wrapper in which I want to make class WinHandle a friend of class Widget (to access some protected members). Is it recommended? Or should I just access them using the traditional Get/Set functions?
Friend is used for granting selective access, just like the protected access specifier. It's also hard to come up with proper use case where use of protected is really useful.
In general, friend classes are useful in designs where there is intentional strong coupling: you need to have a special relationship between two classes. More specifically, one class needs access to another classes's internals and you don't want to grant access to everyone by using the public access specifier.
The rule of thumb: If public is too weak and private is too strong, you need some form of selected access: either protected or friend (the package access specifier in Java serves the same kind of role).
Example design
For instance, I once wrote a simple stopwatch class where I wanted to have the native stopwatch resolution to be hidden, yet to let the user query the elapsed time with a single method and the units to be specified as some sort of variable (to be selected by user preferences, say). Rather than, have say elapsedTimeInSeconds(), elapsedTimeInMinutes(), etc. methods, I wanted to have something like elapsedTime(Unit::seconds). To achive both of these goals, I can't make the native resolution public nor private, so I came up with the following design.
Implementation overview
class StopWatch;
// Enumeration-style class. Copy constructor and assignment operator lets
// client grab copies of the prototype instances returned by static methods.
class Unit
{
friend class StopWatch;
double myFactor;
Unit ( double factor ) : myFactor(factor) {}
static const Unit native () { return Unit(1.0); }
public:
// native resolution happens to be 1 millisecond for this implementation.
static const Unit millisecond () { return native(); }
// compute everything else mostly independently of the native resolution.
static const Unit second () { return Unit(1000.0 / millisecond().myFactor); }
static const Unit minute () { return Unit(60.0 / second().myFactor); }
};
class StopWatch
{
NativeTimeType myStart;
// compute delta using `NativeNow()` and cast to
// double representing multiple of native units.
double elapsed () const;
public:
StopWatch () : myStart(NativeNow()) {}
void reset () { myStart = NativeNow(); }
double elapsed ( const Unit& unit ) const { return elapsed()*unit.myFactor; }
};
As you can see, this design achieves both goals:
native resolution is never exposed
desired time unit can be stored, etc.
Discussion
I really like this design because the original implementation stored the multiple of native time units and performed a division to compute the elapsed time. After someone complained the division was too slow, I changed the Unit class to cache the dividend, making the elapsed() method (a little) faster.
In general, you should strive for strong cohesion and weak coupling. This is why friend is so little used, it is recommended to reduce coupling between classes. However, there are situations where strong coupling gives better encapsulation. In those cases, you probably need a friend.
Do Inherited Classes have the same friends as there base classes? e.g if i declare class foo as a friend of class base, will class der (derived from base) also have foo as a friend?
The rule with friend keyword is:
Friendship attribute is not inherited.
So No friend of base class will not be friend of Derived class.
What are the special case situations when a friend class should be used?
Frankly, (IMHO) using friend classes is mostly done to achieve some things for rather ease of usage. If a software is designed taking in to consideration all the requirememtens then there would practically no need of friend classes. Important to note perfect designs hardly exist and if they do they are very difficult to acheive.
An example case which needs friend class:
Sometimes there may be a need for a tester class(which is not part of the release software) to have access to internals of classes to examine and log certain specific results/diagnostics. It makes sense to use friend class in such a scenario for ease of usage and preventing overhead of design.
I am making a winapi wrapper in which I want to make class WinHandle a friend of class Widget (to access some protected members). Is it recommended? Or should I just access them using the traditional Get/Set functions?
I would stick to the traditional setter/getter. I rather avoid using friend where I can get working through usual OOP construct. Perhaps, I am rather paranoid about using friend because if my classes change/expand in future I perceive the non inheritance attribute of friend causing me problems.
EDIT:
The comments from #Martin, and the excellent answer from #André Caron, provide a whole new perspective about usage of friendship, that I had not encountered before & hence not accounted for in the answer above. I am going to leave this answer as is, because it helped me learn a new perspective & hopefully it will help learn folks with a similar outlook.
friend usually accounts for where you would normally use one single class, but you have to use more because they have different life-times or instance counts, for example. friendship is not transferred or inherited or transitive.
Get/Set is quite terrible, although better than it could be. friend allows you to limit the damage to just one class. Usually you will make an intermediary class which is friended.
class MyHandleIntermediary;
class MyHandle {
friend class MyHandleIntermediary;
private:
HANDLE GetHandle() const;
};
class MyWidget;
class MyHandleIntermediary {
friend class MyWidget;
static HANDLE GetHandle(const MyWidget& ref) {
return ref.GetHandle();
}
};
class MyWidget {
// Can only access GetHandle() and public
};
This allows you to change the accessibility of friendship on a per-member level and ensures that the extra accessibility is documented in a single place.
One of the cases where I applied the "friend classes", is where one class is composed or referenced by other (objects) classes, and the composing objects, require access to the internals of the main class.
enum MyDBTableButtonBarButtonKind {
GoFirst,
GoPrior,
GoNext,
GoLast
}
class MyDBTableButtonBarButtonWidget;
class MyDBTableButtonBarWidget {
friend class MyDBTableButtonBarButtonWidget;
// friend access method:
protected:
void GoFirst();
void GoPrior();
void GoNext();
void GoLast();
void DoAction(MyDBTableButtonBarButtonKind Kind);
};
class MyDBTableButtonBarButtonWidget {
private:
MyDBTableButtonBarWidget* Toolbar;
public:
MyDBTableButtonBarButtonWidget(MyDBTableButtonBarWidget* AButtonBar) {
this ButtonBar = AButtonBar;
}
MyDBTableButtonBarButtonKind Kind;
public:
virtual void Click() { Buttonbar->DoAction(this Kind); };
};
void MyDBTableButtonBarWidget::DoAction(MyDBTableButtonBarButtonKind Kind)
{
switch (Kind)
{
case MyDBTableButtonBarButtonKind::GoFirst:
this.GoFirst();
break;
case MyDBTableButtonBarButtonKind::GoLast:
this.GoLast();
break;
}
}
In this example, there is a widget control that is a bar composed of buttons, the buttonbar is referenced to a D.B. table, and has several buttons for a specific action,
like select the first record of the table, edit, move to the next.
In order to do so, each button class has friend access to private & protected methods, of the given control. As previous answer in this post, usually friend classes act a single class, decomposed in several smaller classes.
It's not a finished example, its only a general idea.
I have a simple, low-level container class that is used by a more high-level file class. Basically, the file class uses the container to store modifications locally before saving a final version to an actual file. Some of the methods, therefore, carry directly over from the container class to the file class. (For example, Resize().)
I've just been defining the methods in the file class to call their container class variants. For example:
void FileClass::Foo()
{
ContainerMember.Foo();
}
This is, however, growing to be a nuisance. Is there a better way to do this?
Here's a simplified example:
class MyContainer
{
// ...
public:
void Foo()
{
// This function directly handles the object's
// member variables.
}
}
class MyClass
{
MyContainer Member;
public:
void Foo()
{
Member.Foo();
// This seems to be pointless re-implementation, and it's
// inconvenient to keep MyContainer's methods and MyClass's
// wrappers for those methods synchronized.
}
}
Well, why not just inherit privatly from MyContainer and expose those functions that you want to just forward with a using declaration? That is called "Implementing MyClass in terms of MyContainer.
class MyContainer
{
public:
void Foo()
{
// This function directly handles the object's
// member variables.
}
void Bar(){
// ...
}
}
class MyClass : private MyContainer
{
public:
using MyContainer::Foo;
// would hide MyContainer::Bar
void Bar(){
// ...
MyContainer::Bar();
// ...
}
}
Now the "outside" will be able to directly call Foo, while Bar is only accessible inside of MyClass. If you now make a function with the same name, it hides the base function and you can wrap base functions like that. Of course, you now need to fully qualify the call to the base function, or you'll go into an endless recursion.
Additionally, if you want to allow (non-polymorphical) subclassing of MyClass, than this is one of the rare places, were protected inheritence is actually useful:
class MyClass : protected MyContainer{
// all stays the same, subclasses are also allowed to call the MyContainer functions
};
Non-polymorphical if your MyClass has no virtual destructor.
Yes, maintaining a proxy class like this is very annoying. Your IDE might have some tools to make it a little easier. Or you might be able to download an IDE add-on.
But it isn't usually very difficult unless you need to support dozens of functions and overrides and templates.
I usually write them like:
void Foo() { return Member.Foo(); }
int Bar(int x) { return Member.Bar(x); }
It's nice and symmetrical. C++ lets you return void values in void functions because that makes templates work better. But you can use the same thing to make other code prettier.
That's delegation inheritance and I don't know that C++ offers any mechanism to help with that.
Consider what makes sense in your case - composition (has a) or inheritance (is a) relationship between MyClass and MyContainer.
If you don't want to have code like this anymore, you are pretty much restricted to implementation inheritance (MyContainer as a base/abstract base class). However you have to make sure this actually makes sense in your application, and you are not inheriting purely for the implementation (inheritance for implementation is bad).
If in doubt, what you have is probably fine.
EDIT: I'm more used to thinking in Java/C# and overlooked the fact that C++ has the greater inheritance flexibility Xeo utilizes in his answer. That just feels like nice solution in this case.
This feature that you need to write large amounts of code is actually necessary feature. C++ is verbose language, and if you try to avoid writing code with c++, your design will never be very good.
But the real problem with this question is that the class has no behaviour. It's just a wrapper which does nothing. Every class needs to do something other than just pass data around.
The key thing is that every class has correct interface. This requirement makes it necessary to write forwarding functions. The main purpose of each member function is to distribute the work required to all data members. If you only have one data member, and you've not decided yet what the class is supposed to do, then all you have is forwarding functions. Once you add more member objects and decide what the class is supposed to do, then your forwarding functions will change to something more reasonable.
One thing which will help with this is to keep your classes small. If the interface is small, each proxy class will only have small interface and the interface will not change very often.
Can someone please point me towards some nice resources for understanding and using nested classes? I have some material like Programming Principles and things like this IBM Knowledge Center - Nested Classes
But I'm still having trouble understanding their purpose. Could someone please help me?
Nested classes are cool for hiding implementation details.
List:
class List
{
public:
List(): head(nullptr), tail(nullptr) {}
private:
class Node
{
public:
int data;
Node* next;
Node* prev;
};
private:
Node* head;
Node* tail;
};
Here I don't want to expose Node as other people may decide to use the class and that would hinder me from updating my class as anything exposed is part of the public API and must be maintained forever. By making the class private, I not only hide the implementation I am also saying this is mine and I may change it at any time so you can not use it.
Look at std::list or std::map they all contain hidden classes (or do they?). The point is they may or may not, but because the implementation is private and hidden the builders of the STL were able to update the code without affecting how you used the code, or leaving a lot of old baggage laying around the STL because they need to maintain backwards compatibility with some fool who decided they wanted to use the Node class that was hidden inside list.
Nested classes are just like regular classes, but:
they have additional access restriction (as all definitions inside a class definition do),
they don't pollute the given namespace, e.g. global namespace. If you feel that class B is so deeply connected to class A, but the objects of A and B are not necessarily related, then you might want the class B to be only accessible via scoping the A class (it would be referred to as A::Class).
Some examples:
Publicly nesting class to put it in a scope of relevant class
Assume you want to have a class SomeSpecificCollection which would aggregate objects of class Element. You can then either:
declare two classes: SomeSpecificCollection and Element - bad, because the name "Element" is general enough in order to cause a possible name clash
introduce a namespace someSpecificCollection and declare classes someSpecificCollection::Collection and someSpecificCollection::Element. No risk of name clash, but can it get any more verbose?
declare two global classes SomeSpecificCollection and SomeSpecificCollectionElement - which has minor drawbacks, but is probably OK.
declare global class SomeSpecificCollection and class Element as its nested class. Then:
you don't risk any name clashes as Element is not in the global namespace,
in implementation of SomeSpecificCollection you refer to just Element, and everywhere else as SomeSpecificCollection::Element - which looks +- the same as 3., but more clear
it gets plain simple that it's "an element of a specific collection", not "a specific element of a collection"
it is visible that SomeSpecificCollection is also a class.
In my opinion, the last variant is definitely the most intuitive and hence best design.
Let me stress - It's not a big difference from making two global classes with more verbose names. It just a tiny little detail, but imho it makes the code more clear.
Introducing another scope inside a class scope
This is especially useful for introducing typedefs or enums. I'll just post a code example here:
class Product {
public:
enum ProductType {
FANCY, AWESOME, USEFUL
};
enum ProductBoxType {
BOX, BAG, CRATE
};
Product(ProductType t, ProductBoxType b, String name);
// the rest of the class: fields, methods
};
One then will call:
Product p(Product::FANCY, Product::BOX);
But when looking at code completion proposals for Product::, one will often get all the possible enum values (BOX, FANCY, CRATE) listed and it's easy to make a mistake here (C++0x's strongly typed enums kind of solve that, but never mind).
But if you introduce additional scope for those enums using nested classes, things could look like:
class Product {
public:
struct ProductType {
enum Enum { FANCY, AWESOME, USEFUL };
};
struct ProductBoxType {
enum Enum { BOX, BAG, CRATE };
};
Product(ProductType::Enum t, ProductBoxType::Enum b, String name);
// the rest of the class: fields, methods
};
Then the call looks like:
Product p(Product::ProductType::FANCY, Product::ProductBoxType::BOX);
Then by typing Product::ProductType:: in an IDE, one will get only the enums from the desired scope suggested. This also reduces the risk of making a mistake.
Of course this may not be needed for small classes, but if one has a lot of enums, then it makes things easier for the client programmers.
In the same way, you could "organise" a big bunch of typedefs in a template, if you ever had the need to. It's a useful pattern sometimes.
The PIMPL idiom
The PIMPL (short for Pointer to IMPLementation) is an idiom useful to remove the implementation details of a class from the header. This reduces the need of recompiling classes depending on the class' header whenever the "implementation" part of the header changes.
It's usually implemented using a nested class:
X.h:
class X {
public:
X();
virtual ~X();
void publicInterface();
void publicInterface2();
private:
struct Impl;
std::unique_ptr<Impl> impl;
}
X.cpp:
#include "X.h"
#include <windows.h>
struct X::Impl {
HWND hWnd; // this field is a part of the class, but no need to include windows.h in header
// all private fields, methods go here
void privateMethod(HWND wnd);
void privateMethod();
};
X::X() : impl(new Impl()) {
// ...
}
// and the rest of definitions go here
This is particularly useful if the full class definition needs the definition of types from some external library which has a heavy or just ugly header file (take WinAPI). If you use PIMPL, then you can enclose any WinAPI-specific functionality only in .cpp and never include it in .h.
I don't use nested classes much, but I do use them now and then. Especially when I define some kind of data type, and I then want to define a STL functor designed for that data type.
For example, consider a generic Field class that has an ID number, a type code and a field name. If I want to search a vector of these Fields by either ID number or name, I might construct a functor to do so:
class Field
{
public:
unsigned id_;
string name_;
unsigned type_;
class match : public std::unary_function<bool, Field>
{
public:
match(const string& name) : name_(name), has_name_(true) {};
match(unsigned id) : id_(id), has_id_(true) {};
bool operator()(const Field& rhs) const
{
bool ret = true;
if( ret && has_id_ ) ret = id_ == rhs.id_;
if( ret && has_name_ ) ret = name_ == rhs.name_;
return ret;
};
private:
unsigned id_;
bool has_id_;
string name_;
bool has_name_;
};
};
Then code that needs to search for these Fields can use the match scoped within the Field class itself:
vector<Field>::const_iterator it = find_if(fields.begin(), fields.end(), Field::match("FieldName"));
One can implement a Builder pattern with nested class. Especially in C++, personally I find it semantically cleaner. For example:
class Product{
public:
class Builder;
}
class Product::Builder {
// Builder Implementation
}
Rather than:
class Product {}
class ProductBuilder {}
I think the main purpose of making a class to be nested instead of just a friend class is the ability to inherit nested class within derived one. Friendship is not inherited in C++.
You also can think about first class ass type of main function, where You initiate all needed classes to work togheter. Like for example class Game, initiate all other classes like windows, heroes, enemy's, levels and so on. This way You can get rid all that stuff from main function it self. Where You can create obiect of Game, and maybe do some extra external call not related to Gemente it self.