Family.h
Code: Select all
#pragma once
#include <cstdlib>
#include <string>
#include <iostream>
class Family
{
public:
class Child
{
public:
Child ( Family& family, const std::string& name );
void PrintName ( );
private:
std::string name_;
Family& family_;
};
Family ( const std::string& family_name );
private:
std::string family_name_;
};
Code: Select all
#include "Family.h"
Family::Family ( const std::string& family_name ) : family_name_ ( family_name )
{
}
Family::Child::Child ( Family& family, const std::string& name ) : family_ ( family ), name_ ( name )
{
}
void Family::Child::PrintName ( )
{
std::cout << name_ << ' ' << family_.family_name_;
}
Code: Select all
#include <cstdlib>
#include <iostream>
#include "Family.h"
int main ( void )
{
Family family ( "Smith" );
Family::Child child1 ( family, "Bob" );
Family::Child child2 ( family, "Sarah" );
Family::Child child3 ( family, "Vladmir Uthmaniyah R'lyeh" );
std::cout << "Name: "; child1.PrintName ( ); std::cout << std::endl;
std::cout << "Name: "; child2.PrintName ( ); std::cout << std::endl;
std::cout << "Name: "; child3.PrintName ( ); std::cout << std::endl;
system ( "pause" );
return 1;
}
Family.h
Code: Select all
#pragma once
#include <cstdlib>
#include <string>
class Family
{
public:
friend class Child;
Family ( const std::string& family_name );
private:
std::string family_name_;
};
Code: Select all
#include "Family.h"
Family::Family ( const std::string& family_name ) : family_name_ ( family_name )
{
}
Code: Select all
#include <cstdlib>
#include <string>
#include "Family.h"
class Child
{
public:
Child ( Family& family, const std::string& name );
void PrintName ( );
private:
std::string name_;
Family& family_;
};
Code: Select all
#include "Child.h"
#include <iostream>
Child::Child ( Family& family, const std::string& name ) : family_ ( family ), name_ ( name )
{
}
void Child::PrintName ( )
{
std::cout << name_ << ' ' << family_.family_name_;
}
Family.h
Code: Select all
#pragma once
#include <cstdlib>
#include <string>
class Family
{
public:
class Child;
Family ( const std::string& family_name );
private:
std::string family_name_;
};
Code: Select all
#include "Family.h"
Family::Family ( const std::string& family_name ) : family_name_ ( family_name )
{
}
Code: Select all
#include <cstdlib>
#include <string>
#include "Family.h"
class Family::Child
{
public:
Child ( Family& family, const std::string& name );
void PrintName ( );
private:
std::string name_;
Family& family_;
};
Code: Select all
#include "Child.h"
#include <iostream>
Family::Child::Child ( Family& family, const std::string& name ) : family_ ( family ), name_ ( name )
{
}
void Family::Child::PrintName ( )
{
std::cout << name_ << ' ' << family_.family_name_;
}
- Purpose and access is made clear.
Using the friend keyword, it it not made clear that Child can access Family's private members from just looking at the Child code alone(Remember, the friend declaration is in Family and not Child). Other programmers would also have a harder time figuring out what the purpose of the class is since it doesn't seem to be coded to be general purpose. Declaring the Child inside Family, you will need to define the class as Family::Child making it clear that Child is a class that is part of a system of classes inside family and is geared towards coordinating with the other classes within that system. - The names inside the hierarchy do not pollute the global scope.
Having names like ListNode and GraphNode can be redundant especially if you are only going to use them in their respective systems that they manage. Declaring these classes in their respective systems removes their names from the global scope and as a result, you can just call them Node and remove the naming redundancy. - Full encapsulation is made possible.
You have the option of fully encapsulating a class within its system by declaring the class as a private member. Even if you #include "Child.h" outside of Family, if it is declared as private, both the compiler and intellisense won't let you have access to it making the class completely invisible outside of the Family class. - Intellisense immediately informs you of a name discrepancy.
This one is a minor nitpick but if you somehow made a mistake in declaring the name of a subclass(like declaring it as Children in Family when you define it as Child), intellisense would immediately inform you of the discrepancy when you define the class(class Family::Child would cause intellisense to freak out since it was declared as Children). Using the friend keyword, you won't find out about this until you realise that you can't access the private members of Family inside Child.