Wednesday, July 8, 2009

Inheritance

A class defines a new type that extends the type system of the language. In languages like C++, a type is a skeleton for an area of memory containing values that follow a particular format. For instance, an integer may be 32 bits of binary number in the 2s complement format; a float may be 32 bits of binary number in the IEEE floating-point format. However, a type may also be seen as a model for a type of object found in the real world.
Things in the real world are classified into groupings called natural types. Each natural type has a number of attributes, called properties that are possessed by all the objects of that type. For instance, the class of all cats is a type with many properties, such as warm-blooded, four-legged, hairy and whiskered. All cats have these properties, and the presence of these properties distinguishes cats from, for instance, humans, which are warm-blooded and hairy, but only have two legs, and no whiskers. When we represent such classes using C++, we could duplicate the common properties like this:
class human { };
class cat { };However, we can leave the common properties in the human class, and allow the cat class to inherit these properties, avoiding the duplication:
class cat : public human { };Of course, we should also stop the inheritance of the property four-legged, and we can do that by over-riding a property with another of the same name. See C++ inheritance for the details.

Function scope

Braces also define the scope of a function's body. Variable names declared locally can be contained anywhere between the braces. One minor break in the rules is that any parameters declared in the function header are also considered to be inside the function's scope (whereas the function name itsef is not). e.g. in
int Function(int a, int b) { int c = a + b;}all the names a, b and c are considered local to the function. The name Function is non-local.

Function member definition

If a function member is not defined as inline, then it must be defined outside the class. This done by prefixing the function name with the class name and the scope-resolution operator, :: (colon-colon). This qualifies the name to avoid ambiguity when function names are reused in different classes. This appears to break the rules of scope, because references to variables declared within the scope of the class are allowed in function member definitions. The rules are merely being extended, however, if it is accepted that the definition of the function is "really" contained in the class, but is just placed externally for readability purposes. It also provides a declaration versus implementation view that abstract data typing demands. An exmple of external definition is:
class Ext {private: int privateVariable;public: void extFun(); ...};
void Ext::extFun() { privateVariable = 10; // reference to name in the class scope}

Function members

An object may contain functions which are stored internally and are unique to that object. Each such function needs an appropriate declaration, as a prototype, in the class.
Function members can be ordinary functions, but they can be overloaded, have default parameter values, or be virtual.
Special function members are constructors and the destructor. In the example below, there are two (overloaded) functions called f1, one private and one public; two constructors, one private and one public, and one destructor;
class C {private: void f1(int); C();public: void f1(int, int); C(int); ~C();};
Function members can be called using the same member access operator as data members.

Friend

Classes can also control access to their private members by using the friend declaration. There are two variations on this:
Access can be granted to individual member functions of another class by using the following form: friend return type X::f(param types...);
any number of functions can be granted access in this manner. Access can be granted to all the functions of a class by: friend class X;
The best way to think about friend functions is that although they are actually declared in another scope, the friend declaration "imports" them into the scope of the declaration, thus allowing direct access to private members.
Of course, since friend functions are not member functions access still has to be through an object of the class declaring the friend.
For example, the function FR in class B, below is granted access to the private member x of class A, but still has to use an object of type A to effect the access:
class A {private: int x;...friend void B::FR();};
class B {... void FR() { A a; cout << a.x; // direct access allowed by friend declaration }...};

File scope

File scope
Names declared outside any function or class have file scope, since their only boundary is the file in which the name occurs. The compiler can link the same name with file scope across files, or this can be prevented by using the keyword static. These names are typically called global.

Encapsulation

Variables in C++ are subject to two constraints. One is the rules of scope, and the other is access control. Encapsulation allows the programmer to control both the scope of names, and access to functions and/or values stored inside an object. The main construct is the class, which allows both variables and functions to be declared within it. These names are subject to visibility rules, and can be declared as having private, or public access.

Dynamic Allocation

Dynamic AllocationC++ allows the program to create and destroy objects at run-time, under program control. Two global operators, new and delete, make this happen.
The operator new takes a class name as argument, together with optional arguments that are passed to the appropriate class constructor, if available. It returns a pointer to the new object, which is created on the heap. A variable of type pointer-to-class can hold this returned value. For example:
class X { ... };
X* obj = new X;
In this case, the default constructor is called, since there are no arguments mentioned. However in: class X {...public: X(int x);...};
X* obj = new X(32);
the constructor with a single integer parameter is used to initialize the new object. Pointer variables follow the usual rules of scope, so it is possible for the variable to be deleted, leaving the object to which it points stranded (the "dangling pointer" problem). To avoid this, objects created with new should be deleted before this happens. For example:
class X { ... };
void f1() { X* x = new X; ... delete x;}
Without the delete operation, the variable x would disappear, leaving the object to which it points without a pointer. Of course, pointers can be returned from functions, so they can be used with delete at a later time. The operator delete calls the destructor function for the class of the argument.

Destructor functions

Destructor functionsThe destructor function is a special function that a class uses to recover the space allocated to an instance of that class. The destructor is called whenever an object goes out of scope. Every class has a destructor function even if none is defined. In this case the equivalent definition is
~X() {}
Where X is the name of the class. Note there is no return type (just like the constructor functions), there are no parameters and the tilde (~) must be present. Destructors should be public to be of any use. There can only be one destructor for a class, but its body can be defined in any chosen fashion. Typically the destructor can use delete on pointers initialized with new to ensure that dangling pointers are not left.
For example, in the class below, the constructor creates a data member with new, and the destructor destroys it.
class Y { ... };
class X {private: Y* mem1;public: X() { mem1 = new Y; } ~X() { delete mem1; }};

Default arguments

Default argumentsThe parameter list of a function signature can specify a default value associated with a parameter. Only the last n consecutive parameters can have a default value, the first n consecutive parameters can have no default. In both cases, n can be zero. Defaults must be specified at the time of declaration of the function, or the function can be declared and defined simultaneously, as it is with inline functions. An example is:
void df(int, float, int = 12, char = 'A');This can be called in one of three ways:
df(10, 2.2); // defaults used for parameters three and fourdf(10, 2.2, 32); // default only used for last onedf(10, 2.2, 32, 'B'); // both defaults are over-riddenDefault arguments are a kind of function overloading.
Defaults can only be specified once. If a function is declared and then defined later, the definition must not mention the defaults:
void f(int = 10);...void f(int x) {...}

Data Members

object may contain values which are stored internally and are unique to that object. In order to do this, each value needs an appropriate declaration as a data member in the class. A data member may be of any type, including classes already defined, pointers to objects of any type, or even references to objects of any type.
Data members may be private or public, but are usually held private so that values may only be changed at the discretion of the class function members. In the example below, the class C contains two a private data member of type int, and a public data member of type pointer to char.
class C {private: int x;public: float f;};

C++

C++ is a language developed by Bjarne Stroustrup and many others at Bell Labs from the language C.
The major concepts in C++ are encapsulation, inheritance, and polymorphism.
Programming style can follow abstract data types, structured programming, and object-oriented design, although C++ can also support familiar programming styles since it contains (almost) the whole of ANSI C.

Constructor functions

Constructor

Every class has at least one constructor function, even when none is declared. The job of a constructor functions is to allocate space for an object, and to set its initial internal state by assigning values to some or all of its data members.
There may be any number of different constructors, since function members may be overloaded. However, all must have the same name as the class that contains them, and none may have a return type. The constructor which takes no arguments is the default constructor. If no constructor is declared at all, the compiler will create a standard default constructor that allocates space but does no initialization.
A special constructor is the copy constructor which takes one object of the same type as an argument through a reference parameter, and copies it to create a new one. Below are some examples:
class C {private: int x;public: C() { x = 0; } // the default constructor C(int xx) { x = xx; } // an overloaded constructor C(C &orig) { x = orig.x; } // the copy constructor };

Class scope

Class scopeNames declared inside the braces of a class declaration are local to that class. They can be data members or function members. e.g. in
class ScopeExample { int Variable; void Function();};the names Variable and Function are local to the class declaration and can be re-used in another scope. The name ScopeExample, however cannot be re-used in the same scope since it is not between the braces.

Classes

Classes
The declaration of a class adds a new type to C++ type system. A class is an encapsulation of variable and function declarations, called data members and function members respectively. Variables can have any type, , but they must have unique names within the scope of the class. Functions can have the same name, even within the scope, but must have different signatures (the functions can be overloaded). All members are subject to access control; the default is private, but any member can be made public by using an access control keyword within the body of the class declaration. Function members may be simply declared as prototypes, or defined within the class as inline functions. Function members may be defined externally. Special function members are constructors, and the destructor. Here is an example class declaration showing all these points:class Eg {
int i1; // a private data member of base type int
C *c; // a private pointer to an object of type C
public:
Eg() { i1 = 0; c = 0; } // the (public) default
// constructor,defined inline
Eg(int ii) { i1 = i; } // an overloaded constructor
~Eg(); // the prototype for the
// destructor
void f1(int); // a prototype for a public
// function member
private:
void f1(int, int); // a prototype for a
// (private)overloaded function
int f2() { cout << "f2" << endl; } // an inline private
// function
public:
int i2; // a public data member
float f3(int, float); // a prototype for a public function
};