Friday, September 17, 2010

Modifying Java Variables (w.r.t c and c++)

Modifying Simple Variable
The only mechanism for changing the value of a simple Java variable is an assignment statement. Java assignment syntax is identical to C assignment syntax. As in C, an assignment replaces the value of a variable named on the left- hand side of the equals sign by the value of the expression on the right- hand side of the equals sign.

Modifying Object Variable 
Java object variables can be changed in two ways. Like simple variables, you can make assignments to object variables. When this is done the object referenced by the variable is not changed. Instead, the reference is replaced by a reference to a different object.
With a few exceptions, the only other thing that you can do with an object variable is to send it a message. This is an important part of any Java program, allowing communication between objects.


Wednesday, September 15, 2010

Java and CPP - the differences and similarities

This list of similarities and differences is based heavily on The Java Language Environment, A White Paper by James Gosling and Henry McGilton http://java.sun.com/doc/language_environment/ and the soon-to-be published book, Thinking in Java by Bruce Eckel, http://www.EckelObjects.com/. At least these were the correct URLs at one point in time. Be aware, however, that the web is a dynamic environment and the URLs may change in the future.
Java does not support typedefs, defines, or a preprocessor. Without a preprocessor, there are no provisions for including header files.
Since Java does not have a preprocessor there is no concept of #define macros or manifest constants. However, the declaration of named constants is supported in Java through use of the final keyword.
Java does not support enums but, as mentioned above, does support named constants.
Java supports classes, but does not support structures or unions.
All stand-alone C++ programs require a function named main and can have numerous other functions, including both stand-alone functions and functions, which are members of a class. There are no stand-alone functions in Java. Instead, there are only functions that are members of a class, usually called methods. Global functions and global data are not allowed in Java.
All classes in Java ultimately inherit from the Object class. This is significantly different from C++ where it is possible to create inheritance trees that are completely unrelated to one another.
All function or method definitions in Java are contained within the class definition. To a C++ programmer, they may look like inline function definitions, but they aren't. Java doesn't allow the programmer to request that a function be made inline, at least not directly.
Both C++ and Java support class (static) methods or functions that can be called without the requirement to instantiate an object of the class.
The interface keyword in Java is used to create the equivalence of an abstract base class containing only method declarations and constants. No variable data members or method definitions are allowed. (True abstract base classes can also be created in Java.) The interface concept is not supported by C++.
Java does not support multiple inheritance. To some extent, the interface feature provides the desirable features of multiple inheritance to a Java program without some of the underlying problems.
While Java does not support multiple inheritance, single inheritance in Java is similar to C++, but the manner in which you implement inheritance differs significantly, especially with respect to the use of constructors in the inheritance chain.
In addition to the access specifiers applied to individual members of a class, C++ allows you to provide an additional access specifier when inheriting from a class. This latter concept is not supported by Java.
Java does not support the goto statement (but goto is a reserved word). However, it does support labeled break and continue statements, a feature not supported by C++. In certain restricted situations, labeled break and continue statements can be used where a goto statement might otherwise be used.
Java does not support operator overloading.
Java does not support automatic type conversions (except where guaranteed safe).
Unlike C++, Java has a String type, and objects of this type are immutable (cannot be modified). Quoted strings are automatically converted into String objects. Java also has a StringBuffer type. Objects of this type can be modified, and a variety of string manipulation methods are provided.
Unlike C++, Java provides true arrays as first-class objects. There is a length member, which tells you how big the array is. An exception is thrown if you attempt to access an array out of bounds. All arrays are instantiated in dynamic memory and assignment of one array to another is allowed. However, when you make such an assignment, you simply have two references to the same array. Changing the value of an element in the array using one of the references changes the value insofar as both references are concerned.
Unlike C++, having two "pointers" or references to the same object in dynamic memory is not necessarily a problem (but it can result in somewhat confusing results). In Java, dynamic memory is reclaimed automatically, but is not reclaimed until all references to that memory become NULL or cease to exist. Therefore, unlike in C++, the allocated dynamic memory cannot become invalid for as long as it is being referenced by any reference variable.
Java does not support pointers (at least it does not allow you to modify the address contained in a pointer or to perform pointer arithmetic). Much of the need for pointers was eliminated by providing types for arrays and strings. For example, the oft-used C++ declaration char* ptr needed to point to the first character in a C++ null-terminated "string" is not required in Java, because a string is a true object in Java.
A class definition in Java looks similar to a class definition in C++, but there is no closing semicolon. Also forward reference declarations that are sometimes required in C++ are not required in Java.
The scope resolution operator (::) required in C++ is not used in Java. The dot is used to construct all fully-qualified references. Also, since there are no pointers, the pointer operator (->) used in C++ is not required in Java.
In C++, static data members and functions are called using the name of the class and the name of the static member connected by the scope resolution operator. In Java, the dot is used for this purpose.
Like C++, Java has primitive types such as int, float, etc. Unlike C++, the size of each primitive type is the same regardless of the platform. There is no unsigned integer type in Java. Type checking and type requirements are much tighter in Java than in C++.
Unlike C++, Java provides a true boolean type.
Conditional expressions in Java must evaluate to boolean rather than to integer, as is the case in C++. Statements such as if(x+y)... are not allowed in Java because the conditional expression doesn't evaluate to a boolean.
The char type in C++ is an 8-bit type that maps to the ASCII (or extended ASCII) character set. The char type in Java is a 16-bit type and uses the Unicode character set (the Unicode values from 0 through 127 match the ASCII character set). For information on the Unicode character set see http://www.stonehand.com/unicode.html.
Unlike C++, the >> operator in Java is a "signed" right bit shift, inserting the sign bit into the vacated bit position. Java adds an operator that inserts zeros into the vacated bit positions.
C++ allows the instantiation of variables or objects of all types either at compile time in static memory or at run time using dynamic memory. However, Java requires all variables of primitive types to be instantiated at compile time, and requires all objects to be instantiated in dynamic memory at runtime. Wrapper classes are provided for all primitive types except byte and short to allow them to be instantiated as objects in dynamic memory at runtime if needed.
C++ requires that classes and functions be declared before they are used. This is not necessary in Java.
The "namespace" issues prevalent in C++ are handled in Java by including everything in a class, and collecting classes into packages.
C++ requires that you re-declare static data members outside the class. This is not required in Java.
In C++, unless you specifically initialize variables of primitive types, they will contain garbage. Although local variables of primitive types can be initialized in the declaration, primitive data members of a class cannot be initialized in the class definition in C++.
In Java, you can initialize primitive data members in the class definition. You can also initialize them in the constructor. If you fail to initialize them, they will be initialized to zero (or equivalent) automatically.
Like C++, Java supports constructors that may be overloaded. As in C++, if you fail to provide a constructor, a default constructor will be provided for you. If you provide a constructor, the default constructor is not provided automatically.
All objects in Java are passed by reference, eliminating the need for the copy constructor used in C++.
(In reality, all parameters are passed by value in Java.  However, passing a copy of a reference variable makes it possible for code in the receiving method to access the object referred to by the variable, and possibly to modify the contents of that object.  However, code in the receiving method cannot cause the original reference variable to refer to a different object.)
There are no destructors in Java. Unused memory is returned to the operating system by way of a garbage collector, which runs in a different thread from the main program. This leads to a whole host of subtle and extremely important differences between Java and C++.
Like C++, Java allows you to overload functions. However, default arguments are not supported by Java.
Unlike C++, Java does not support templates. Thus, there are no generic functions or classes.
Unlike C++, several "data structure" classes are contained in the "standard" version of Java. More specifically, they are contained in the standard class library that is distributed with the Java Development Kit (JDK). For example, the standard version of Java provides the containers Vector and Hashtable that can be used to contain any object through recognition that any object is an object of type Object. However, to use these containers, you must perform the appropriate upcasting and downcasting, which may lead to efficiency problems.
Multithreading is a standard feature of the Java language.
Although Java uses the same keywords as C++ for access control: private, public, and protected, the interpretation of these keywords is significantly different between Java and C++.
There is no virtual keyword in Java. All non-static methods always use dynamic binding, so the virtual keyword isn't needed for the same purpose that it is used in C++.
Java provides the final keyword that can be used to specify that a method cannot be overridden and that it can be statically bound. (The compiler may elect to make it inline in this case.)
The detailed implementation of the exception handling system in Java is significantly different from that in C++.
Unlike C++, Java does not support operator overloading. However, the (+) and (+=) operators are automatically overloaded to concatenate strings, and to convert other types to string in the process.
As in C++, Java applications can call functions written in another language. This is commonly referred to as native methods. However, applets cannot call native methods.
Unlike C++, Java has built-in support for program documentation. Specially written comments can be automatically stripped out using a separate program named javadoc to produce program documentation.
Generally Java is more robust than C++ due to the following:
  • Object handles (references) are automatically initialized to null.
  • Handles are checked before accessing, and exceptions are thrown in the event of problems.
  • You cannot access an array out of bounds.
  • Memory leaks are prevented by automatic garbage collection.

C++ ACCESSORS AND MUTATORS TUTORIAL

• I. INTRODUCTION

Hello; nice to meet you! Welcome to the “C++ Accessors and Mutators Tutorial.”

The tutorial assumes you are familiar with the following vocabulary:

1. Instantiation is declaring an object of a class type.

2. Encapsulation is the idea of an object containing data and functions that operate on that data.

3. A class is a user defined type.

4. Inheritance allows the creation of hierarchical classifications.

5. Polymorphism is Greek for “many shapes;” which becomes manipulating “many types” through a common interface. Polymorphism gives a programmer “programming in the general” instead of “programming in the specific.”

6. Object-oriented programming (OOP) is the use of inheritance, run-time polymorphism, encapsulation, and the programming style of defining your own data types as classes.

• II. PRIVATE DATA MEMBERS

The variables declared as part of the class are data members. Data hiding occurs when access control is established by data members being declared in the private area of the body of a class definition. The private access specifier prevents direct access to the class data members. However, private data members can be accessed indirectly by public accessor and mutator member functions and friends of that class.

• III. CONSTRUCTORS

When data members are declared they can not be initialized in the class body. Therefore, constructors are used to initialize the class data members when the class objects are instantiated.

• IV. GOOD ACCESSOR CHARACTERISTICS

Accessors or get functions:

1. Read or obtain the value of private member variables.

This must be done in a manner that maintains the integrity of the private member data.

2. Display the value of private member variables.

The displayed information should be user friendly, i.e., formatted in a fashion easily readable and understandably by the user.

3. Print the value of private member variables.

When an inappropriate attempt is made to change the value of a private data member, a properly written get function with good characteristics will be programmed to notify the user. User management should receive written notification of all inappropriate activity as soon as it occurs.

• V. GOOD MUTATOR CHARACTERISTICS

Mutators or set functions:

1. Modify the value of private data members.

Public set functions set the value of private data members. However, set functions should not just change data. Set functions must be programmed to make sure what they are being called to do is correct before they do it. Properly written set functions are the first line of defense against, “garbage in, garbage out.”

2. Validate the value of private data members.

When an inappropriate attempt is made to change the value of a private data member, a properly written set function will be programmed to prevent the modification.

• VI. ADVANTAGES OF USING GET AND SET FUNCTIONS

The main advantages of always using get and set public class member functions is faster, more efficient, and less expensive program maintenance.

1. All data usage updates only have to be made to the appropriate public get member functions.

2. All data value storage updates only have to be made to the appropriate public set member functions.

• VII. SUMMARY

The names of the accessor and mutator member functions do not have to begin with get and set; however, the naming convention is a generally accepted programming practice.

In general, get and set functions are a public interface for read/write access to private data members.

Even though all class member functions can indirectly access private data members, the programmer should ensure the program is written so that all member functions call the appropriate get and set functions when interacting with private data members.

Monday, September 6, 2010

Basic tokens in perl

Comments

A common Perl-pitfall is to write cryptic code. In that context, Perl do provide for comments, albeit not very flexible. Perl treats any thing from a hash # to the end of line as a comment. Block comments are not possible. So, if you want to have a block of comments, you must ensure that each line starts with #.

Statements

Everything other than comments are Perl statements, which must end with a semicolon, like the last line above. Unlike C, you need not put a wrapping character \ for long statements. A Perl statement always ends with a semicolon.

Thursday, September 2, 2010

Inheritance in c++

Good practise to access elements by methods rather than by direct

Overload the postfix and prefix version of ++


//prefix version of ++
 ThreeD ThreeD::operator++() 

  x++; // increment x, y, and z  
  y++;  
  z++; 
  return *this


//postfix operator ++
ThreeD ThreeD::operator++(int notused

 
  x++;  // increment x, y, and z 
  y++; 
  z++; 
  return *this; // return original value 
}

Which Operator are not overloaded

There are certain operators in the available set that cannot be overloaded. The general reason for the restriction is safety. If these operators were overloadable, it would somehow jeopardize or break safety mechanisms, make things harder, or confuse existing practice.
  • The member selection operator.. Currently, the dot has a meaning for any member in a class, but if you allow it to be overloaded, then you couldn’t access members in the normal way; instead you’d have to use a pointer and the arrow operator->.
  • The pointer to member dereference operator.*, for the same reason as operator..
  • There’s no exponentiation operator. The most popular choice for this was operator** from Fortran, but this raised difficult parsing questions. Also, C has no exponentiation operator, so C++ didn’t seem to need one either because you can always perform a function call. An exponentiation operator would add a convenient notation, but no new language functionality to account for the added complexity of the compiler.
  • There are no user-defined operators. That is, you can’t make up new operators that aren’t currently in the set. Part of the problem is how to determine precedence, and part of the problem is an insufficient need to account for the necessary trouble.
  • You can’t change the precedence rules. They’re hard enough to remember as it is without letting people play with them.

Member access in C++

Member access determines if a class member is accessible in an expression or declaration. Suppose x is a member of class A. Class member x can be declared to have one of the following levels of accessibility:

public: x can be used anywhere without the access restrictions defined by private or protected.
private: x can be used only by the members and friends of class A.
protected: x can be used only by the members and friends of class A, and the members and friends of classes derived from class A.
Members of classes declared with the keyword class are private by default. Members of classes declared with the keyword struct or union are public by default.

To control the access of a class member, you use one of the access specifiers public, private, or protected as a label in a class member list. The following example demonstrates these access specifiers:



struct A {
friend class C;
private:
int a;
public:
int b;
protected:
int c;
};

struct B : A {
void f() {
// a = 1;
b = 2;
c = 3;
}
};

struct C {
void f(A x) {
x.a = 4;
x.b = 5;
x.c = 6;
}
};

int main() {
A y;
// y.a = 7;
y.b = 8;
// y.c = 9;

B z;
// z.a = 10;
z.b = 11;
// z.c = 12;
}
The following table lists the access of data members A::a A::b, and A::c in various scopes of the above example.
Scope A::a A::b A::c
function B::f() No access. Member A::a is private. Access. Member A::b is public. Access. Class B inherits from A.
function C::f() Access. Class C is a friend of A. Access. Member A::b is public. Access. Class C is a friend of A.
object y in
main()
No access. Member y.a is private. Access. Member y.a is public. No access. Member y.c is protected.
object z in main() No access. Member z.a is private. Access. Member z.a is public. No access. Member z.c is protected.
An access specifier specifies the accessibility of members that follow it until the next access specifier or until the end of the class definition. You can use any number of access specifiers in any order. If you later define a class member within its class definition, its access specification must be the same as its declaration. The following example demonstrates this:
class A {
class B;
public:
class B { };
};
The compiler will not allow the definition of class B because this class has already been declared as private.
A class member has the same access control regardless whether it has been defined within its class or outside its class.
Access control applies to names. In particular, if you add access control to a typedef name, it affects only the typedef name. The following example demonstrates this:
class A {
class B { };
public:
typedef B C;
};

int main() {
A::C x;
// A::B y;
}
The compiler will allow the declaration A::C x because the typedef name A::C is public. The compiler would not allow the declaration A::B y because A::B is private.

Wednesday, September 1, 2010

Static function members in C+

Static member functions (C++ only)
You cannot have static and nonstatic member functions with the same names and the same number and type of arguments.
Like static data members, you may access a static member function f() of a class A without using an object of class A.
A static member function does not have a this pointer.

Eg.
class X
{
private:
   static int si;
public:
   static void set_si(int arg) { si = arg; }
};


Static member functions (C++ only)
The compiler does not allow the member access operation this->si in function A::print_si() because this member function has been declared as static, and therefore does not have a this pointer.
You can call a static member function using the this pointer of a nonstatic member function. In the following example, the nonstatic member function printall() calls the static member function f() using the this pointer:
#include < iostream >
using namespace std;

class C {
static void f() {
cout << "Here is i: " << i << endl;
}
static int i;
int j;
public:
C(int firstj): j(firstj) { }
void printall();
};

void C::printall() {
cout << "Here is j: " << this->j << endl;
this->f();
}

int C::i = 3;

int main() {
C obj_C(0);
obj_C.printall();
}
 
A static member function cannot be declared with the keywords virtual, const, volatile, or const volatile.
A static member function can access only the names of static members, enumerators, and nested types of the class in which it is declared. Suppose a static member function f() is a member of class X. The static member function f() cannot access the nonstatic members X or the nonstatic members of a base class of X.

Const data members in c++

Static data member in c++ classes

Note: Static data member are already initialised to 0, but still you should initialise explicitly using method 2.
Here are the two ways I was talking about :
First One:

class class1{

private:

public:


class1(){}


static int DataMember;


static void initFun()

{ DataMember = 10 ; }

};



Second One:


class class2{

private:

public:


class2(){}


static int DataMember2;


};

int class2::DataMember2 = 10 ;
Once you define a static data member, it exists even though no objects of the static data member's class exist. In the above example, no objects of class X exist even though the static data member X::i has been defined.

Static data members of a class in namespace scope have external linkage. The initializer for a static data member is in the scope of the class declaring the member.

A static data member can be of any type except for void or void qualified with const or volatile. You cannot declare a static data member as mutable.

You can only have one definition of a static member in a program. Unnamed classes, classes contained within unnamed classes, and local classes cannot have static data members.

Static data members and their initializers can access other static private and protected members of their class.

Using friend to overload operators

class loc {
  int longitude, latitude;
public:
  loc() {}
  loc(int lg, int lt) {
    longitude = lg;
    latitude = lt;
  }
   
  void show() {
    cout << longitude << " ";
    cout << latitude << "\n";
  }
   
  loc operator=(loc op2);
  friend loc operator++(loc &op);
  friend loc operator--(loc &op);
};

loc operator++(loc &op)
{
  op.longitude++;
  op.latitude++;
   
  return op;
}
   
// Make op-- a friend; use reference.
loc operator--(loc &op)
{
  op.longitude--;
  op.latitude--;
   
  return op;
}
 

Types of constructors

1. Void constructors or default constructors
This has no parameters and  is must in case of dynamic allocation of objects.


2. Default parameter constructor
A default parameter is a function parameter that has a default value provided to it. If the user does not supply a value for this parameter, the default value will be used. If the user does supply a value for the default parameter, the user-supplied value is used.

3 Private constructors

4. Parametric constructor
It is good practice to try not to overload the constructors. It is best to declare only one constructor and give it default parameters wherever possible:



using namespace std;

#include <iostream>
class vector{public: double x; double y; vector (double a = 0, double b = 0) { x = a; y = b; }};int main (){ vector k; cout << "vector k: " << k.x << ", " << k.y << endl << endl; vector m (45, 2); cout << "vector m: " << m.x << ", " << m.y << endl << endl; vector p (3); cout << "vector p: " << p.x << ", " << p.y << endl << endl; return 0;}output:vector k: 0, 0vector m: 45, 2vector p: 3, 0

The stack and the heap

The memory a program uses is typically divided into four different areas:
  • The code area, where the compiled program sits in memory.
  • The globals area, where global variables are stored.
  • The heap, where dynamically allocated variables are allocated from.
  • The stack, where parameters and local variables are allocated from.
There isn’t really much to say about the first two areas. The heap and the stack are where most of the interesting stuff takes place, and those are the two that will be the focus of this section.
The heap
The heap (also known as the “free store”) is a large pool of memory used for dynamic allocation. In C++, when you use the new operator to allocate memory, this memory is assigned from the heap.
1int *pValue = new int; // pValue is assigned 4 bytes from the heap
2int *pArray = new int[10]; // pArray is assigned 40 bytes from the heap
Because the precise location of the memory allocated is not known in advance, the memory allocated has to be accessed indirectly — which is why new returns a pointer. You do not have to worry about the mechanics behind the process of how free memory is located and allocated to the user. However, it is worth knowing that sequential memory requests may not result in sequential memory addresses being allocated!
1int *pValue1 = new int;
2int *pValue2 = new int;
3// pValue1 and pValue2 may not have sequential addresses
When a dynamically allocated variable is deleted, the memory is “returned” to the heap and can then be reassigned as future allocation requests are received.
The heap has advantages and disadvantages:
1) Allocated memory stays allocated until it is specifically deallocated (beware memory leaks).
2) Dynamically allocated memory must be accessed through a pointer.
3) Because the heap is a big pool of memory, large arrays, structures, or classes should be allocated here.
The stack
The call stack (usually referred to as “the stack”) has a much more interesting role to play. Before we talk about the call stack, which refers to a particular portion of memory, let’s talk about what a stack is.
Consider a stack of plates in a cafeteria. Because each plate is heavy and they are stacked, you can really only do one of three things:
1) Look at the surface of the top plate
2) Take the top plate off the stack
3) Put a new plate on top of the stack
In computer programming, a stack is a container that holds other variables (much like an array). However, whereas an array lets you access and modify elements in any order you wish, a stack is more limited. The operations that can be performed on a stack are identical to the ones above:
1) Look at the top item on the stack (usually done via a function called top())
2) Take the top item off of the stack (done via a function called pop())
3) Put a new item on top of the stack (done via a function called push())
A stack is a last-in, first-out (LIFO) structure. The last item pushed onto the stack will be the first item popped off. If you put a new plate on top of the stack, anybody who takes a plate from the stack will take the plate you just pushed on first. Last on, first off. As items are pushed onto a stack, the stack grows larger — as items are popped off, the stack grows smaller.
The plate analogy is a pretty good analogy as to how the call stack works, but we can actually make an even better analogy. Consider a bunch of mailboxes, all stacked on top of each other. Each mailbox can only hold one item, and all mailboxes start out empty. Furthermore, each mailbox is nailed to the mailbox below it, so the number of mailboxes can not be changed. If we can’t change the number of mailboxes, how do we get a stack-like behavior?
First, we use a marker (like a post-it note) to keep track of where the bottom-most empty mailbox is. In the beginning, this will be the lowest mailbox. When we push an item onto our mailbox stack, we put it in the mailbox that is marked (which is the first empty mailbox), and move the marker up one mailbox. When we pop an item off the stack, we move the marker down one mailbox and remove the item from that mailbox. Anything below the marker is considered “on the stack”. Anything at the marker or above the marker is not on the stack.
This is almost exactly analogous to how the call stack works. The call stack is a fixed-size chunk of sequential memory addresses. The mailboxes are memory addresses, and the “items” are pieces of data (typically either variables or addreses). The “marker” is a register (a small piece of memory) in the CPU known as the stack pointer. The stack pointer keeps track of where the top of the stack currently is.
The only difference between our hypothetical mailbox stack and the call stack is that when we pop an item off the call stack, we don’t have to erase the memory (the equivalent of emptying the mailbox). We can just leave it to be overwritten by the next item pushed to that piece of memory. Because the stack pointer will be below that memory location, we know that memory location is not on the stack.
So what do we push onto our call stack? Parameters, local variables, and… function calls.
The stack in action
Because parameters and local variables essentially belong to a function, we really only need to consider what happens on the stack when we call a function. Here is the sequence of steps that takes place when a function is called:
  1. The address of the instruction beyond the function call is pushed onto the stack. This is how the CPU remembers where to go after the function returns.
  2. Room is made on the stack for the function’s return type. This is just a placeholder for now.
  3. The CPU jumps to the function’s code.
  4. The current top of the stack is held in a special pointer called the stack frame. Everything added to the stack after this point is considered “local” to the function.
  5. All function arguments are placed on the stack.
  6. The instructions inside of the function begin executing.
  7. Local variables are pushed onto the stack as they are defined.
When the function terminates, the following steps happen:
  1. The function’s return value is copied into the placeholder that was put on the stack for this purpose.
  2. Everything after the stack frame pointer is popped off. This destroys all local variables and arguments.
  3. The return value is popped off the stack and is assigned as the value of the function. If the value of the function isn’t assigned to anything, no assignment takes place, and the value is lost.
  4. The address of the next instruction to execute is popped off the stack, and the CPU resumes execution at that instruction.
Typically, it is not important to know all the details about how the call stack works. However, understanding that functions are effectively pushed on the stack when they are called and popped off when they return gives you the fundamentals needed to understand recursion, as well as some other concepts that are useful when debugging.
Stack overflow
The stack has a limited size, and consequently can only hold a limited amount of information. If the program tries to put too much information on the stack, stack overflow will result. Stack overflow happens when all the memory in the stack has been allocated — in that case, further allocations begin overflowing into other sections of memory.
Stack overflow is generally the result of allocating too many variables on the stack, and/or making too many nested function calls (where function A calls function B calls function C calls function D etc…) Overflowing the stack generally causes the program to crash.
Here is an example program that causes a stack overflow. You can run it on your system and watch it crash:
1int main()
2{
3    int nStack[100000000];
4    return 0;
5}
This program tries to allocate a huge array on the stack. Because the stack is not large enough to handle this array, the array allocation overflows into portions of memory the program is not allowed to use. Consequently, the program crashes.
The stack has advantages and disadvantages:
  • Memory allocated on the stack stays in scope as long as it is on the stack. It is destroyed when it is popped off the stack.
  • All memory allocated on the stack is known at compile time. Consequently, this memory can be accessed directly through a variable.
  • Because the stack is relatively small, it is generally not a good idea to do anything that eats up lots of stack space. This includes allocating large arrays, structures, and classes, as well as heavy recursion.

Private constructors

Occasionally, we do not want users outside of a class to use particular constructors. To enforce this behavior, we can make constructors private. Just like regular private functions, private constructors can only be accessed from within the class. Let’s take a look at an example of this:
01class Book
02{
03private:
04    int m_nPages;
05 
06    // This constructor can only be used by Book's members
07    Book() // private default constructor
08    {
09         m_nPages = 0;
10    }
11 
12public:
13    // This constructor can be used by anybody
14    Book(int nPages) // public non-default constructor
15    {
16        m_nPages = nPages;
17    }
18};
19 
20int main()
21{
22    Book cMyBook; // fails because default constructor Book() is private
23    Book cMyOtherBook(242); // okay because Book(int) is public
24 
25    return 0;
26}
One problem with public constructors is that they do not provide any way to control how many of a particular class may be created. If a public constructor exists, it can be used to instantiate as many class objects as the user desires. Often it is useful to restrict users to being able to create only one instance of a particular class. Classes that can only be instantiated once are called singletons. There are many ways to implement singletons, but most of them involve use of a private (or protected) constructor to prevent users from instantiating as many of the class as they want.
Constructor chaining and initialization issues
When you instantiate a new object, the object’s constructor is called implicitly by the C++ compiler. Let’s take a look at two related situations that often cause problems for new programmers:
First, sometimes a class has a constructor which needs to do the same work as another constructor, plus something extra. The process of having one constructor call another constructor is called constructor chaining. Although some languages such as C# support constructor chaining, C++ does not. If you try to chain constructors, it will usually compile, but it will not work right, and you will likely spend a long time trying to figure out why, even with a debugger. However, constructors are allowed to call non-constructor functions in the class. Just be careful that any members the non-constructor function uses have already been initialized.
Although you may be tempted to copy code from the first constructor into the second constructor, having duplicate code makes your class harder to understand and more burdensome to maintain. The best solution to this issue is to create a non-constructor function that does the common initialization, and have both constructors call that function.
For example, the following:
01class Foo
02{
03public:
04    Foo()
05    {
06        // code to do A
07    }
08 
09    Foo(int nValue)
10    {
11        // code to do A
12        // code to do B
13    }
14};
becomes:
01class Foo
02{
03public:
04    Foo()
05    {
06        DoA();
07    }
08 
09    Foo(int nValue)
10    {
11        DoA();
12        // code to do B
13    }
14 
15    void DoA()
16    {
17        // code to do A
18    }
19};
Code duplication is kept to a minimum, and no chained constructor calls are needed.
Second, you may find yourself in the situation where you want to write a member function to re-initialize a class back to default values. Because you probably already have a constructor that does this, you may be tempted to try to call the constructor from your member function. As mentioned, chaining constructor calls are illegal in C++. You could copy the code from the constructor in your function, which would work, but lead to duplicate code. The best solution in this case is to move the code from the constructor to your new function, and have the constructor call your function to do the work of initializing the data:
01class Foo
02{
03public:
04    Foo()
05    {
06        Init();
07    }
08 
09    Foo(int nValue)
10    {
11        Init();
12        // do something with nValue
13    }
14 
15    void Init()
16    {
17        // code to init Foo
18    }
19};
It is fairly common to include an Init() function that initializes member variables to their default values, and then have each constructor call that Init() function before doing it’s parameter-specific tasks. This minimizes code duplication and allows you to explicitly call Init() from wherever you like.
One small caveat: be careful when using Init() functions and dynamically allocated memory. Because Init() functions can be called by anyone at any time, dynamically allocated memory may or may not have already been allocated when Init() is called. Be careful to handle this situation appropriately — it can be slightly confusing, since a non-null pointer could be either dynamically allocated memory or an uninitialized pointer!

Constructors in c++

When an object of a class is created, C++ calls the constructor for that class. If no constructor is defined, C++ invokes a default constructor, which allocates memory for the object, but doesn't initialize it.

Why you should define a constructor

Uninitialized member fields have garbage in them. This creates the possibility of a serious bug (eg, an uninitialized pointer, illegal values, inconsistent values, ...).

Declaring a constructor

A constructor is similar to a function, but with the following differences.
  • No return type.
  • No return statement.
Example [extracts from three different files].
//=== point/point.h =================================================
#ifndef POINT_H
#define POINT_H
class Point {
public:
Point(); // parameterless default constructor
Point(int new_x, int new_y); // constructor with parameters
int getX();
int getY();
private:
int x;
int y;
};
#endif
Here is part of the implementation file.
//=== point/point.cpp ==============================================
. . .
Point::Point() { // default constructor
x = 0;
y = 0;
}

Point::Point(int new_x, int new_y) { // constructor
x = new_x;
y = new_y;
}
. . .
And here is part of a file that uses the Point class.
//=== point/main.cpp ==============================================
. . .
Point p; // calls our default constructor
Point q(10,20); // calls constructor with parameters
Point* r = new Point(); // calls default constructor
Point s = p; // our default constructor not called.
. . .

Classes in c++

History of C++

Bjarne Stroustrup of Bell Labs extended the C language to be capable of Object-Oriented Programming (OOP), and it became popular in the 1990's as C++. There were several enhancements, but the central change was extending struct to allow it to contain functions and use inheritance. These extended structs were later renamed classes. A C++ standard was established in 1999, so there are variations in the exact dialect that is accepted by pre-standard compilers.

Public and Private parts

All member fields in a class are private by default (no code outside the class can reference them), whereas fields of a struct are public, meaning that anyone can use them. For example,
struct Product {
char mfg_id[4]; // 4 char code for the manufacturer.
char prod_id[8]; // 8-char code for the product
int price; // price of the product in dollars.
int qty_on_hand; // quantity on hand in inventory
};
could be rewritten as a class like this
class Product {
public:
char mfg_id[4]; // 4 char code for the manufacturer.
char prod_id[8]; // 8-char code for the product
int price; // price of the product in dollars.
int qty_on_hand; // quantity on hand in inventory
};

Data member initializers

Initializing data members

There are two ways to initialize data members.
  • Explicit assignments in a constructor.
  • In a member initializer in the constructor header.

Member initializer syntax

The definition (not the prototype) header is followed by a colon, the name of the field, and a parenthesized initial value. Separate multiple initializations with commas.
Insert example here

Member initializer required in the following cases

  • To initialize const data members.
  • To initialize references.
  • To initialize member objects. If a member initializer is not provided, the default constructor for that class will be called.
  • To initialize base class members.

Destructors

When are destructors called?

A destructor for an object is called whenever
  • The scope of a local variable or parameter is exited, the destructor is called.
  • By explicitly calling the destructor.

Default constructor vs custom constructor

If you don't have anything to clean up, like memory that you allocated for some of the members, then the default constructor is probably ok.

This pointer


Copy Constructors

When copies of objects are made

A copy constructor is called whenever a new variable is created from an object. This happens in the following cases (but not in assignment).
  • A variable is declared which is initialized from another object, eg,
    Person q("Mickey"); // constructor is used to build q.
    Person r(p); // copy constructor is used to build r.
    Person p = q; // copy constructor is used to initialize in declaration.
    p = q; // Assignment operator, no constructor or copy constructor.
  • A value parameter is initialized from its corresponding argument.
    f(p);               // copy constructor initializes formal value parameter.
  • An object is returned by a function.
C++ calls a copy constructor to make a copy of an object in each of the above cases. If there is no copy constructor defined for the class, C++ uses the default copy constructor which copies each field, ie, makes a shallow copy.

Don't write a copy constructor if shallow copies are ok

If the object has no pointers to dynamically allocated memory, a shallow copy is probably sufficient. Therefore the default copy constructor, default assignment operator, and default destructor are ok and you don't need to write your own.

If you need a copy constructor, you also need a destructor and operator=

If you need a copy constructor, it's because you need something like a deep copy, or some other management of resources. Thus is is almost certain that you will need a destructor and override the assignment operator.

Copy constructor syntax

The copy constructor takes a reference to a const parameter. It is const to guarantee that the copy constructor doesn't change it, and it is a reference because a value parameter would require making a copy, which would invoke the copy constructor, which would make a copy of its parameter, which would invoke the copy constructor, which ...
Here is an example of a copy constructor for the Point class, which doesn't really need one because the default copy constructor's action of copying fields would work fine, but it shows how it works.
//=== file Point.h =============================================
class Point {
public:
. . .
Point(const Point& p); // copy constructor
. . .
//=== file Point.cpp ==========================================
. . .
Point::Point(const Point& p) {
x = p.x;
y = p.y;
}

. . .
//=== file my_program.cpp ====================================
. . .
Point p; // calls default constructor
Point s = p; // calls copy constructor.
p = s; // assignment, not copy constructor.

Difference between copy constructor and assignment

A copy constructor is used to initialize a newly declared variable from an existing variable. This makes a deep copy like assignment, but it is somewhat simpler:
  1. There is no need to test to see if it is being initialized from itself.
  2. There is no need to clean up (eg, delete) an existing value (there is none).
  3. A reference to itself is not returned.

Unaddressed issue

[Question: When is the base (parent) class copy constructor called? Is it like Java and the parent constructor is called at the beginning of each constructor? Does it have to be explicit?]

Shallow vs deep copy

A shallow copy of an object copies all of the member field values. This works well if the fields are values, but may not be what you want for fields that point to dynamically allocated memory. The pointer will be copied. but the memory it points to will not be copied -- the field in both the original object and the copy will then point to the same dynamically allocated memory, which is not usually what you want. The default copy constructor and assignment operator make shallow copies.
A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. To make a deep copy, you must write a copy constructor and overload the assignment operator, otherwise the copy will point to the original, with disasterous consequences.

Deep copies need ...

If an object has pointers to dynamically allocated memory, and the dynamically allocated memory needs to be copied when the original object is copied, then a deep copy is required.
A class that requires deep copies generally needs:

Classes in c++

History of C++

Bjarne Stroustrup of Bell Labs extended the C language to be capable of Object-Oriented Programming (OOP), and it became popular in the 1990's as C++. There were several enhancements, but the central change was extending struct to allow it to contain functions and use inheritance. These extended structs were later renamed classes. A C++ standard was established in 1999, so there are variations in the exact dialect that is accepted by pre-standard compilers.

Public and Private parts

All member fields in a class are private by default (no code outside the class can reference them), whereas fields of a struct are public, meaning that anyone can use them. For example,
struct Product {
char mfg_id[4]; // 4 char code for the manufacturer.
char prod_id[8]; // 8-char code for the product
int price; // price of the product in dollars.
int qty_on_hand; // quantity on hand in inventory
};
could be rewritten as a class like this
class Product {
public:
char mfg_id[4]; // 4 char code for the manufacturer.
char prod_id[8]; // 8-char code for the product
int price; // price of the product in dollars.
int qty_on_hand; // quantity on hand in inventory
};

OOP Terminology

Along with each programming revolution comes a new set of terminology. There are some new OOP concepts, but many have a simple analog in pre-OOP practice.
OOP Term Definition
method Same as function, but the typical OO notation is used for the call, ie, f(x,y) is written x.f(y) where x is an object of class that contains this f method.
send a messageCall a function (method)
instantiateAllocate a class/struct object (ie, instance) with new
class A struct with both data and functions
object Memory allocated to a class/struct. Often allocated with new.
member A field or function is a member of a class if it's defined in that class
constructorFunction-like code that initializes new objects (structs) when they instantiated (allocated with new).
destructorFunction-like code that is called when an object is deleted to free any resources (eg, memory) that is has pointers to.
inheritanceDefining a class (child) in terms of another class (parent). All of the public members of the public class are available in the child class.
polymorphismDefining functions with the same name, but different parameters.
overload A function is overloaded if there is more than one definition. See polymorphism.
override Redefine a function from a parent class in a child class.
subclass Same as child, derived, or inherited class.
superclassSame as parent or base class.
attribute Same as data member or member field.

Object-Oriented Programming

History: The Rise and Decline of Structured Programming

For many years (roughly 1970 to 1990), structured programming was the most common way to organize a program. This is characterized by a functional-decomposition style - breaking the algorithms in to every smaller functions. This technique was a great improvement over the ad hoc programming which preceded it. However, as programs became larger, structured programming was not able control the exponential increase in complexity.

The Problem - Complexity

Complexity measurements grow exponentially as the size of programs grow. One measurement is coupling, or much different elements (modules, data structures) interact with each other. The fewer the connections, the less complex a program is. Low coupling is highly desirable.
There have been several post-structured programming attempts to control complexity. One of these is to use software components - preconstructed software "parts" to avoid programming. And when you have to program, use object-oriented programming (OOP).

Object-Oriented Programming (OOP)

Object-Oriented Programming groups related data and functions together in a class, generally making data private and only some functions public. Restricting access decreases coupling and increases cohesion. While it is not a panacea, it has proven to be very effective in reducing the complexity increase with large programs. For small programs may be difficult to see the advantage of OOP over, eg, structured programming because there is little complexity regardless of how it's written. Many of the mechanics of OPP are easy to demonstrate; it is somewhat harder to create small, convincing examples.
OOP is often said to incorporate three techniques: inheritance, encapsulation, and polymorphism. Of these, you should first devote yourself to choosing the right classes (possibly difficult) and getting the encapsulation right (fairly easy). Inheritance and polymorphism are not even present in many programs, so you can ignore them at that start.

Encapsulation

Encapsulation is grouping data and functions together and keeping their implementation details private. Greatly restricting access to functions and data reduces coupling, which increases the ability to create large programs.
Classes also encourage coherence, which means that a given class does one thing. By increasing coherence, a program becomes easier to understand, more simply organized, and this better organization is reflected in a further reduction in coupling.

Inheritance

Inheritance means that a new class can be defined in terms of an existing class. There are three common terminologies for the new class: the derived class, the child class, or the subclass. The original class is the base class, the parent class, or the superclass. The new child class inherits all capabilities of the parent class and adds its own fields and methods. Altho inheritance is very important, especially in many libraries, is often not used in an application.

Polymorphism

Polymorphism is the ability of different functions to be invoked with the same name. There are two forms.
Static polymorphism is the common case of overriding a function by providing additional definitions with different numbers or types of parameters. The compiler matches the parameter list to the appropriate function.
Dynamic polymorphism is much different and relies on parent classes to define virtual functions which child classes may redefine. When this virtual member function is called for an object of the parent class, the execution dynamically chooses the appropriate function to call - the parent function if the object really is the parent type, or the child function if the object really is the child type. This explanation is too brief to be usesful without an example, but that will have to be written latter.

Word Length Frequency

// word_len_histo.cpp : reads words and lists distribution
// of word lengths.
// Fred Swartz, 2002-09-01

// This would be nice to turn into an OO program, where
// a class represented a distribution of values.
// Some elements which are globals here would turn into
// private member elements in the class (eg, valueCount).


//--- includes
#include
#include
#include
using namespace std;

//--- prototypes
void countValue(int cnt);
float getAverage();

//--- constants
const int BINS = 21; // how many numbers can be counted

//--- globals
int valueCount[BINS]; // bins used for counting each number
int totalChars = 0; // total number of characters

//=========================================================== main
int main() {

char c; // input character
int wordLen = 0; // 0 if not in word, else word length

//--- Initialize counts to zero
for (int i=0; i
valueCount[i] = 0;
}

//--- Read chars in loop and decide if in a word or not.
while (cin.get(c)) {
if (isalpha(c)) { // letters are in words, so
wordLen++; // add one to the word length
} else {
countValue(wordLen); // end of word
wordLen = 0; // not in a word, set to zero
}
}
countValue(wordLen); // necessary if word ended in EOF

//--- print the number of words of each length
cout << "Why does this line disappear?" << endl;
cout << "Word length Frequency" << endl;
for (int j=1; j
cout << setw(6) << right << j << " "
<< setw(8) << right << valueCount[j] << endl;
}

//--- print average length
cout << "\nAverage word length: " << getAverage() << endl;

return 0;
}//end main


//==================================================== countValue
void countValue(int cnt) {
if (cnt > 0) {
// this must be the end of a word
if (cnt > 20) {
cnt = 20; // longer than 20 counts as 20
}
valueCount[cnt]++; // count in correct bin
}
totalChars += cnt;
}//end countWord


//==================================================== getAverage
float getAverage() {
int totalCount = 0;

for (int i=0; i
totalCount += valueCount[i];
}
if (totalCount > 0) {
return (float)totalChars/totalCount;
} else {
return 0.0;
}
}//end getAverage