These are the reference websites to know about the c++ programming .....
My C+ Website
Engineering Education
All refences about C++
Friend functions
In principle, private and protected members of a class cannot be accessed from outside the same class in which they are declared. However, this rule does not affect friends.
Friends are functions or classes declared as such.
If
we want to declare an external function as friend of a class, thus
allowing this function to have access to the private and protected
members of this class, we do it by declaring a prototype of this
external function within the class, and preceding it with the keyword friend:
// friend functions
#include <iostream>
using namespace std;
class CRectangle {
int width, height;
public:
void set_values (int, int);
int area () {return (width * height);}
friend CRectangle duplicate (CRectangle);
};
void CRectangle::set_values (int a, int b) {
width = a;
height = b;
}
CRectangle duplicate (CRectangle rectparam)
{
CRectangle rectres;
rectres.width = rectparam.width*2;
rectres.height = rectparam.height*2;
return (rectres);
}
int main () {
CRectangle rect, rectb;
rect.set_values (2,3);
rectb = duplicate (rect);
cout << rectb.area();
return 0;
}
| 24
|
The
duplicate function is a friend of CRectangle. From within that function
we have been able to access the members width and heightCRectangle,
which are private members. Notice that neither in the declaration of
duplicate() nor in its later use in main() have we considered duplicate a
member of class CRectangle. It isn't! It simply has access to its
private and protected members without being a member. of different objects of type
The
friend functions can serve, for example, to conduct operations between
two different classes. Generally, the use of friend functions is out of
an object-oriented programming methodology, so whenever possible it is
better to use members of the same class to perform operations with
them. Such as in the previous example, it would have been shorter to
integrate duplicate() within the class CRectangle.
Friend classes
Just as we have the possibility to define a friend function, we can also define a class as friend of another one, granting that first class access to the protected and private members of the second one.// friend class
#include <iostream>
using namespace std;
class CSquare;
class CRectangle {
int width, height;
public:
int area ()
{return (width * height);}
void convert (CSquare a);
};
class CSquare {
private:
int side;
public:
void set_side (int a)
{side=a;}
friend class CRectangle;
};
void CRectangle::convert (CSquare a) {
width = a.side;
height = a.side;
}
int main () {
CSquare sqr;
CRectangle rect;
sqr.set_side(4);
rect.convert(sqr);
cout << rect.area();
return 0;
}
| 16
|
In
this example, we have declared CRectangle as a friend of CSquare so
that CRectangle member functions could have access to the protected and
private members of CSquare, more concretely to CSquare::side, which
describes the side width of the square.
You
may also see something new at the beginning of the program: an empty
declaration of class CSquare. This is necessary because within the
declaration of CRectangle we refer to CSquare (as a parameter in
convert()). The definition of CSquare is included later, so if we did
not include a previous empty declaration for CSquare this class would
not be visible from within the definition of CRectangle.
Consider
that friendships are not corresponded if we do not explicitly specify
so. In our example, CRectangle is considered as a friend class by
CSquare, but CRectangle does not consider CSquare to be a friend, so
CRectangle can access the protected and private members of CSquare but
not the reverse way. Of course, we could have declared also CSquare as
friend of CRectangle if we wanted to.
Another property of friendships is that they are not transitive: The friend of a friend is not considered to be a friend unless explicitly specified.
Inheritance between classes
A key feature of C++ classes is inheritance. Inheritance allows to create classes which are derived from other classes, so that they automatically include some of its "parent's" members, plus its own. For example, we are going to suppose that we want to declare a series of classes that describe polygons like our CRectangle, or like CTriangle. They have certain common properties, such as both can be described by means of only two sides: height and base.
This
could be represented in the world of classes with a class CPolygon from
which we would derive the two other ones: CRectangleCTriangle. and
The
class CPolygon would contain members that are common for both types of
polygon. In our case: width and height. And CRectangle and CTriangle
would be its derived classes, with specific features that are different
from one type of polygon to the other.
Classes
that
are derived from others inherit all the accessible members of the
base class. That means that if a base class includes a member A and we
derive it to another class with another member called B, the derived
class will contain both members A and B.
In order to derive a class from another, we use a colon (:) in the declaration of the derived class using the following format:
class derived_class_name: public base_class_name
{ /*...*/ };
{ /*...*/ };
Where
derived_class_name is the name of the derived class and base_class_name
is the name of the class on which it is based. The public access
specifier may be replaced by any one of the other access specifiers
protected and private. This access specifier describes the minimum
access level for the members that are inherited from the base class.
// derived classes
#include <iostream>
using namespace std;
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b;}
};
class CRectangle: public CPolygon {
public:
int area ()
{ return (width * height); }
};
class CTriangle: public CPolygon {
public:
int area ()
{ return (width * height / 2); }
};
int main () {
CRectangle rect;
CTriangle trgl;
rect.set_values (4,5);
trgl.set_values (4,5);
cout << rect.area() << endl;
cout << trgl.area() << endl;
return 0;
}
| 20
10
|
The
objects of the classes CRectangle and CTriangle each contain members
inherited from CPolygon. These are: width, height and set_values().
The protected access specifier is similar to private.
Its only difference occurs in fact with inheritance. When a class
inherits from another one, the members of the derived class can access
the protected members inherited from the base class, but not its
private members.
Since
we wanted width and height to be accessible from members of the derived
classes CRectangle and CTriangle and not only by members of CPolygon,
we have used protected access instead of private.
We can summarize the different access types according to who can access them in the following way:
Access | public | protected | private |
---|---|---|---|
members of the same class | yes | yes | yes |
members of derived classes | yes | yes | no |
not members | yes | no | no |
Where "not members" represent any access from outside the class, such as from main(), from another class or from a function.
In
our example, the members inherited by CRectangle and CTriangle have the
same access permissions as they had in their base class CPolygon:
CPolygon::width // protected access
CRectangle::width // protected access
CPolygon::set_values() // public access
CRectangle::set_values() // public access
|
This is because we have used the public keyword to define the inheritance relationship on each of the derived classes:
class CRectangle: public CPolygon { ... }
|
This
public keyword after the colon (:) denotes the maximum access level for
all the members inherited from the class that follows it (in this case
CPolygon). Since public
is the most accessible level, by specifying this keyword the derived
class will inherit all the members with the same levels they had in the
base class.
If we specify a more restrictive access level like protected,
all public members of the base class are inherited as protected in the
derived class. Whereas if we specify the most restricting of all access
levels: private, all the base class members are inherited as private.
For example, if daughter was a class derived from mother that we defined as:
class daughter: protected mother;
|
This
would set protected as the maximum access level for the members of
daughter that it inherited from mother. That is, all members that were
public in mother would become protected in daughter. Of course, this
would not restrict daughter to declare its own public members. That
maximum access level is only set for the members inherited from mother.
If
we do not explicitly specify any access level for the inheritance, the
compiler assumes private for classes declared with classstruct. keyword and public for those declared with
What is inherited from the base class?
In principle, a derived class inherits every member of a base class except:- its constructor and its destructor
- its operator=() members
- its friends
Although the constructors and destructors of the base class are
not inherited themselves, its default constructor (i.e., its
constructor with no parameters) and its destructor are always called
when a new object of a derived class is created or destroyed.
If
the base class has no default constructor or you want that an
overloaded constructor is called when a new derived object is created,
you can specify it in each constructor definition of the derived class:
derived_constructor_name (parameters) : base_constructor_name (parameters) {...}
For example:
// constructors and derived classes
#include <iostream>
using namespace std;
class mother {
public:
mother ()
{ cout << "mother: no parameters\n"; }
mother (int a)
{ cout << "mother: int parameter\n"; }
};
class daughter : public mother {
public:
daughter (int a)
{ cout << "daughter: int parameter\n\n"; }
};
class son : public mother {
public:
son (int a) : mother (a)
{ cout << "son: int parameter\n\n"; }
};
int main () {
daughter cynthia (0);
son daniel(0);
return 0;
}
| mother: no parameters
daughter: int parameter
mother: int parameter
son: int parameter
|
Notice
the difference between which mother's constructor is called when a new
daughter object is created and which when it is a sondaughter and son: object. The difference is because the constructor declaration of
daughter (int a) // nothing specified: call default
son (int a) : mother (a) // constructor specified: call this
|
Multiple inheritance
In C++ it is perfectly possible that a class inherits members from more than one class. This is done by simply separating the different base classes with commas in the derived class declaration. For example, if we had a specific class to print on screen (COutput) and we wanted our classes CRectangle and CTriangle to also inherit its members in addition to those of CPolygon we could write:class CRectangle: public CPolygon, public COutput;
class CTriangle: public CPolygon, public COutput;
|
here is the complete example:
// multiple inheritance
#include <iostream>
using namespace std;
class CPolygon {
protected:
int width, height;
public:
void set_values (int a, int b)
{ width=a; height=b;}
};
class COutput {
public:
void output (int i);
};
void COutput::output (int i) {
cout << i << endl;
}
class CRectangle: public CPolygon, public COutput {
public:
int area ()
{ return (width * height); }
};
class CTriangle: public CPolygon, public COutput {
public:
int area ()
{ return (width * height / 2); }
};
int main () {
CRectangle rect;
CTriangle trgl;
rect.set_values (4,5);
trgl.set_values (4,5);
rect.output (rect.area());
trgl.output (trgl.area());
return 0;
}