Tuesday, February 9, 2010

C++: Shallow Copy & Deep Copy (with Copy Constructor and Assignment Operator)

Shallow Copy: Copies only the member field values. If an object stores an integer value10, it copies 10, and if an object stores an address say 0x100, it copies only the address and not the data stored at that address. So when data stored is an address, we don’t have a distinct copy of the object. It is also called Default copy.

Deep Copy: It makes an entirely distinct copy of the object, no matter what the object stores. To perform deep copy, copy-constructor and overloaded assignment operator functions are required.

In order to make duplicate of an object it is necessary either to make a shallow copy or a deep copy of the object. To make copies of some objects, a shallow copy is enough but for some other objects a deep copy is necessary. So the question is how we distinguish what to perform, to copy an object.

This is identified based on how memory is allocated for the object. If the memory is allocated statically, then a shallow copy is required, but if the memory is dynamically allotted then a deep copy is necessary.

Here in this article we try to understand more about shallow and deep copies, by defining copy constructor and assignment operator functions for implementing a circular queue. Also here we try to analyze the difference between copy-constructor and assignment operator.

Example: Circular Queue

In this example not all the functions required to implement a circular queue is defined. Only the functions concerning shallow copy and deep copy are defined. To perform deep copy we need a copy constructor and an overloaded assignment operator.

//START OF CODE

Queue.h (Header File)

class Queue {

public:

//Queue constructor: creates an empty queue.

Queue();

//empty: returns true if the queue is empty; false otherwise.

bool empty();

//enqueue: adds element to the back of the queue.

void enqueue(QueueElement);

//Queue destructor: removes all elements from the queue(heap) so

//memory can be reclaimed.

~Queue();

//Queue copy constructor: allows for making copies of queues.

Queue(Queue&);

//Assignment operator:allows for assignments of queues to each //other.

Queue& operator=(Queue&);

private:

class Node {

public:

QueueElement data;

Node* next;

Node() {

//empty Node constructor: creates an empty node.

//Needed especially for the next pointer.

data = 0;

next = 0;

}

Node(QueueElement thing) {

//Node constructor: creates a node with data in it.

data = thing;

next = 0;

}

};

typedef Node* NodePointer;

NodePointer last;

int mySize;

};

Queue.cpp (Source File)

//Queue constructor: makes an empty queue.

Queue::Queue()

{

last = 0;

mySize = 0;

}

//empty: returns true if the queue is empty; false otherwise.

bool Queue::empty()

{

return (mySize == 0);

}

//enqueue: adds an element to the back of the queue.

void Queue::enqueue(QueueElement thing)

{

NodePointer nuPtr = new Node(thing);

if (mySize == 0) {

//for an empty queue, stick the new element in all applicable slots.

last = nuPtr;

nuPtr->next = nuPtr;

}

else {

//otherwise, we need to file our new member into the back.

nuPtr->next = last->next;

last->next = nuPtr;

last = nuPtr;

}

//increment the size to that size calculations are correct.

mySize++;

}

//Destructor

Queue::~Queue()

{

while (!empty())

dequeue();//definition not included here.

cout << "Queue removed." <<>

}

//Copy constructor definition.

Queue::Queue(Queue& copy)

{

last = 0;

mySize = 0;

NodePointer ptr = copy.last->next;

do {

enqueue(ptr->data);

ptr = ptr->next;

} while (ptr != copy.last->next);

}

//Assignment operator: allows for assignments of queues to each other.

Queue& Queue::operator = (Queue& data)

{

if (this == &data)//(1)checking if LHS and RHS objects are the same, so //it doesn’t result in self-assignment.

{

cout << "You can't do that! You tried self-assignment!" <<>

return (*this);

}

this->~Queue(); //(2) Empty the LHS object, before copying RHS to LHS.

NodePointer ptr = data.last->next;

do {

enqueue(ptr->data);

ptr = ptr->next;

} while (ptr != data.last->next);

return (*this); //(3)Return LHS, the new object to which copy is made.

}

//END OF CODE

Declare the circular queue object.

Queue q1; //Refer to the default constructor definition.

Insert some elements to the queue through the ‘enqueue’ process.

q1.enqueue(10);

q1.enqueue(20);

q1.enqueue(30);

[Refer to the ‘enqueue’ function, where for each new element inserted, memory is allotted dynamically using ‘new’.]

Pictorially the queue looks like the one below.




[Note: As this is a circular queue, we have just one pointer “myBack” pointing to the last node in the queue. Also the last node is connected to the first node making it a circular queue.]

Here ‘q1’ is the name of the queue stored at memory address ‘1000’ and ‘myBack’ is a pointer to ‘q1’ whose address ‘100’ is stored in q1.

Now we need to make a copy of the queue ‘q1’ to another queue object say ‘q2’.

Queue q2 = q1; //Copy constructor.

Here a new circular queue object ‘q2’ is declared and we copy ‘q1’ to ‘q2’.

Upon the occurrence of the above statement (Copy constructor), the compiler identifies a deep-copy is necessary as the memory to queue objects are dynamically allocated. If a copy constructor is defined, then it is called. (Refer to the copy-constructor function in the above code.)

Pictorially this is shown below.


In the above diagram, ‘myBack’ is distinct in ‘q1’ and ‘q2’. Also the copied queue ‘q2’ is at memory address ‘2000’ and ‘q2’ holds the address of its own ‘myBack’ pointer at location ‘200’. These memory addresses clearly specify that ‘q1’ and ‘q2’ are entirely distinct copies.

Suppose, if destroy one queue say q1, still we can access q2 and its elements.

Suppose if copy constructor function is not defined, then upon the execution of the below statement

Queue q2 = q1;

A shallow (default) copy is made. After shallow copy this is the situation.


So if a shallow copy is made for a dynamically allocated object, only the value of the member field (address i.e 100 in this case) of the object is copied and not the entire object. Here ‘q2’ holds the address of the memory location which ‘q1’ is pointing to. So both q1 and q2 are referring to the same memory location.

Suppose, if we destroy a queue, say q1, all the nodes of the queue are destroyed and now if we try to access the other queue object q2, results in an unexpected situation. This is because the memory allocated to q2 was already destroyed using q1, which was also pointing to the same location. So if a shallow copy is made on dynamically created objects, no distinct copy is made and the new object created will point to the memory location of the old object.

Similarly, to do the assignment of one object to another object for which memory is allocated dynamically, we need to overload the assignment (=) operator. (Please refer to the overloaded assignment operator function in the above code sequence.)

Call to copy-constructor and overloaded assignment operator.

Call to Copy-Constructor is like,

Queue q2 = q1;

Call to overloaded assignment operator is like,

Queue q2;

q2 = q1;

[Note: In the above two calls it is assumed the q1 is already defined.]

Many confuse as the call to copy-constructor is actually a call to assignment operator function as it has the presence of assignment operator (=).

Let’s clarify this confusion,

Overloaded assignment operator call: Queue q2; //Line 1

q2 = q1; //Line 2 [Note: q1 is already created.]

In Line-1, the circular queue object q2 is created by calling default constructor.

In Line-2, the object q1 is assigned to already created but empty object q2. This makes a call to overloaded assignment operator function.

Copy-constructor call: Queue q2 = q1;

Here we are trying to assign object q1 to q2, even before q2 is created. So this doesn’t call the default constructor to create q2, but intern makes a call to copy-constructor, which will create object q2 using object q1 and also copy data of q1 to q2.

Differences between Copy-Constructor and Overloaded Assignment operator.

Copy-constructor copies an existing object to a non-existing object, which will be created before copying where as an assignment operation happen between two existing objects.

In both copy-constructor and assignment operations we copy from one object to another object, but in case of overloaded assignment operator function additionally we do the following.

· A check is made to prevent self-assignment.

· Existing values from the LHS object is removed, before copying.

· A reference to itself is returned.

A call to overloaded assignment operator could even be,

Queue q2, q3; //Line 1

q3 = q2 = q1; //Line 2 [It is assumed the object q1 is already created and hold some values]

In Line-1, we are creating two new queue objects q2 and q3.

In Line-2 we are making multiple assignments, which results in multiple calls to overloaded assignment function. First the assignment of q1 to q2 (q2 = q1) is made, followed by the assignment of q2 to q3 (q3=q2). For this reason of supporting multiple assignments, the Assignment operator function returns a reference to itself.

In this article, I have tried to explain the concepts of Shallow copy and Deep copy fusing the concepts of Copy constructor and Overloaded assignment operator. For any question and concerns please leave your comment.

Saturday, January 30, 2010

Creating Threads in C++ using Boost C++ Libraries

At present standard C++, does not support Threads. But there are other open source libraries available like ‘Boost C++’, which provides Threading feature along with many other features. This allows a C++ programmer to go ahead with developing applications that require threading support.

This article explains how to create a thread. Here we create two threads ‘ThreadA’ and ‘ThreadB’ which continuously outputs the text ‘ThreadA output’ and ‘ThreadB output’ to the console accordingly.

So we need to download and configure the Boost C++ libraries with visual studio.
Download Path: http://www.boost.org
Configuration Steps: http://technologicalthemes.blogspot.com/2009/08/configuring-boost-c-library-with-visual.html

After the configuration, create a project and include the following code.
Different parts of the code are explained appropriately, by adding comments in the code.

Main Function: main.cpp

#include"iostream"
#include"string"
#include"boost/thread/thread.hpp"
#include"boost/thread/mutex.hpp"
#include"boost/thread/condition.hpp"

#include"ThreadA.h"
#include"ThreadB.h"

using namespace std;

void main()
{
//Create an object of Thread-A
ThreadA threadA;

//Creating the thread: "ThreadA"
//Argument-1: Call 'thread_A_Function' function in Thread-A.
//Argument-2: Pass an instance of thread.
//NOTE: The two arguments are arguments to the BOOST C++ Thread
//Library, so that it starts the thread. So these two arguments are a must to
//create a thread.
boost::thread thrdA(&ThreadA::thread_A_Function, &threadA);

//As explained for Thread-A, same thing applies for Thread-B.
ThreadB threadB;
boost::thread thrdB(&ThreadB::thread_B_Function, &threadB);

//Initiates the Thread and waits for its completion.
thrdA.join();
thrdB.join();
}

Thread –A:

Header File: ThreadA.h

#ifndef THREADA_H
#define THREADA_H

#include"iostream"
#include"boost/thread/thread.hpp"

class ThreadA
{
public:
ThreadA(void);
~ThreadA(void);
void thread_A_Function();
};

#endif

CPP File: ThreadA.cpp

#ifndef THREADA_CPP
#define THREADA_CPP

#include "ThreadA.h"

ThreadA::ThreadA(void)
{
}

ThreadA::~ThreadA(void)
{
}

//Defining the 'thread_A_Function' Function.
void ThreadA::thread_A_Function()
{
for(;;)
{
std::cout<<"Thread A output"<

//Make the Thread sleep for 1 second.

boost::xtime xt; //create a timer object.
boost::xtime_get(&xt, boost::TIME_UTC); //initialize the timer
//-object to a standard time.
xt.sec += 1; //Set the delay in seconds.
boost::thread::sleep(xt); //make the thread sleep.
}
}

#endif

Thread -B:

Header File: ThreadB.h

#ifndef THREADB_H
#define THREADB_H

#include"iostream"
#include"boost/thread/thread.hpp"

class ThreadB
{
public:
ThreadB(void);
~ThreadB(void);
void thread_B_Function();
};

#endif

CPP File: ThreadB.cpp

#ifndef THREADB_CPP
#define THREADB_CPP

#include "ThreadB.h"

ThreadB::ThreadB(void)
{
}

ThreadB::~ThreadB(void)
{
}

//Defining the 'thread_A_Function' Function.
void ThreadB::thread_B_Function()
{
for(;;)
{
std::cout<<"Thread B output"<

//Make the Thread sleep for 1 second.

boost::xtime xt; //create a timer object.
boost::xtime_get(&xt, boost::TIME_UTC); //initialize the timer object
//to a standard time.
xt.sec += 1; //Set the delay in seconds.
boost::thread::sleep(xt); //make the thread sleep.
}
}

#endif

This example only works with the threading support provided by Boost C++ libraries. The upcoming proposed standard for C++, that is “C++0x” will include threading support.

Friday, December 4, 2009

Configuring Xerces-C++ XML Libraries with Visual Studio 2008

The latest release of Xerces c++ xml library is Xerces-C++ 3.0.1. Download the library from the apache website @ http://xerces.apache.org/xerces-c/download.cgi from any of the available mirrors.

Integrating Xerces-C++ XML Library with Visual Studio 2008

Integration involves 3 main steps. This makes the application utilize the facilities of Xerces- C++ xml libraries, and be fully functional.

1) Set the Library path:-

· Start Visual studio 2008 and open your project.

· Go to Tools > Options…

· On the popped-up ‘options’ window, towards left, select and expand the directory ‘Projects and Solutions’. In the expanded list select ‘VC++ Directories’.

· Now towards the right of ‘Options’ window, click on ‘Show directories for:’ dropdown list and select ‘Library files’.

· Now in the window below, include the path of the Xerces-C++ ‘lib’ directory (Example: C:\xerces-c-3.0.1-x86-windows-vc-8.0\xerces-c-3.0.1-x86-windows-vc-8.0\lib). To do this, click just below the last included path. With this a cursor appears, where we can type the path, or we can even include the path by clicking on the ellipsis button at the end of the line and browse to the Xerces ‘lib’ directory.

· Finally click ‘Ok’.

2) Set the Include path:-

· Follow the first 3 instructions of the previous step.

· Now towards the right of ‘Options’ window, click on ‘Show directories for:’ dropdown list and select ‘Include files’.

· Now in the window below, include the path of the Xerces ‘include’ folder (Example: C:\xerces-c-3.0.1-x86-windows-vc-8.0\xerces-c-3.0.1-x86-windows-vc-8.0\include). To do this, click just below the last included path. With this a cursor appears, where we can type the path, or we can even include the path by clicking on the ellipsis button at the end of the line and browse to the ‘include’ directory.

· Finally click ‘Ok’.

3) Copy the two DLL’s, ‘xerces-c_3_0.dll’ and ‘xerces-c_3_0D.dll’ available in “bin” folder (Example: C:\xerces-c-3.0.1-x86-windows-vc-8.0\xerces-c-3.0.1-x86-windows-vc-8.0\bin) and put It in the system’s Windows folder. (i.e. C:\Windows)

Build and Run the application.

Thursday, September 17, 2009

Differenciating between Platform, Framework and Middleware

Introduction.

We all have used the terms Platform, Framework and Middleware at some point. These three are very necessary as they support the applications we develop and deploy, work as expected. Many a times we normally use these terms interchangeably, but that’s incorrect. Here we attempt to draw boundaries, between these three terminologies.

Definition

Think, you are developing a application, a PLATFORM is one, which provides a base to deploy and run your application, a FRAMEWORK is one which help design, develop and bind together different components to your application, a MIDDLEWARE is one which provides wide variety of services to the application from outside.

Description

Platform: A platform could be hardware architecture and some software, on top of which other applications operate. Hardware architecture is base to any software. More precisely, hardware platform refers to the processor and other hardware devices existing in any computing machine. Upon this hardware we have operating system and other application program. The software platform, for example an operating system forms the base for all other software’s to operate.

Platforms support the application programs by providing some of the following features. They include multi-tasking, memory management, access to disk and file systems, networking, security and several other functions.

Common Examples: Operating software, programming languages, compilers, runtime libraries, Java virtual machine etc.

Framework: A software framework could be a collection of support programs, a scripting language, code libraries and any other software, which help develop and bind together, different components of the software project.

Each library provides a specific functionality. More libraries the framework includes more functionality it provides. The functions provided by the framework are exposed through API’s.

The framework design is highly flexible and reusable. It facilitates software design & development, allowing designers and programmers, denote more time on actual requirement development.

Choosing the best framework for a project often requires a programmer to balance between

(i) How much functionality they get from the framework

(ii) The flexibility they are left with.

The original framework will become a part of the application being developed. I mean, if we ship the application, we ship it along with the framework. There is always a tight bonding between the application and framework it is using.

Examples: Wiki, Blogspot, Java spring framework, Struts framework

Middleware: A middleware provides services to an application. As the name tells, it acts as a mid-level agent, between the service provider and the service consumer. Also, we can say it acts as a glue or mediates between two or more already existing applications.

The middleware allows applications to communicate with one another, where either of the application runs on different platforms and could come from different vendors.

Common services provided by a middleware include, allow programs to establish access to multiple databases, provide messaging services that allow multiple applications to communicate.

Middleware supports your application from outside. That means, our application is not tightly coupled with any of the middleware, instead out application just uses some of its services.

Types of Middleware: Object Request Broker (ORB), Transaction Processing (TP) Monitors, Remote Procedure Call (RPC) systems, Enterprise Service Bus (ESB), Application Servers.

Example: Suppose we need to develop a Content Management System (CMS) that helps to keep all the data related to a particular project at one place. A freely available and widely used CMS is Wiki. Wiki is available in different versions. One has to download the available wiki framework and modify according to the requirements.

Also the wiki can work on many platforms; I mean many different operating systems supports wiki. But it is dependent on one such operating system. The basic framework that we download has to be deployed first, for which we need a operating system platform.

Now we need to make modifications to the wiki framework, add more code, update with new pages such that it suits our requirements. Once the application is ready, data is stored and accessed.

Now, we need to host the wiki, so it is accessible for all over the internet. To host the wiki application across a distributed network, we need certain other external applications like Web Servers and Application servers. So here we say, that these external applications which provides services to the wiki application, by hosting over the network, constitutes for the middleware.

More Information @:

http://www.hildeberto.com/2008/10/platform-versus-framework_12.html

http://www.hildeberto.com/2009/05/what-is-middleware-platform-framework.html

Friday, August 7, 2009

Configuring Boost C++ Library with Visual Studio 2008

I) Download Boost C++ Library

The latest release of Boost library is Version 1.39.0, released in may 2009. This release has the following new libraries and updates over its previous version, Version 1.38.0.

New Libraries : Signals2.

Updated Libraries : Asio, Flyweight, Foreach, Hash, Interprocess, Intrusive, Program.Options, Proto, PtrContainer, Range, Unordered, Xpressive. Updated Tools: Boostbook, Quickbook.

Download path: http://www.boost.org/

II) Integrating Boost C++ libraries with Visual studio 2008

Integration involves two steps. This makes the application utilize the facilities of Boost C++ libraries, and be fully functional.

1) ‘Including’ Boost directory path:-

Steps:-

a) Launch Visual studio 2008.

b) Click on ‘Tools’ menu & select ‘options…’

c) On the popped-up ‘options’ window, towards left, select and expand the directory ‘Projects and Solutions’. In the expanded list select ‘VC++ Directories’.

d) Now towards the right of ‘Options’ window, click on ‘Show directories for:’ dropdown list and select ‘Include files’.

e) Now in the window below, include the path of the Boost C++ ‘root’ directory. To do this, click just below the last included path. With this a cursor appears, where we can type the path, or we can even include the path by clicking on the ellipsis button at the end of the line and browse to the root directory.

f) Finally click on ‘Ok’.

2) ‘Linking’ the Boost libraries with the project.

Steps:-

a) In ‘Solution Explorer’, right click on the project folder and select properties.

b) Now the project properties window pops-up.

c) Towards the left of the properties window, select and expand ‘Configuration properties’ directory.

d) Now select and expand ‘Linker’ directory and click on ‘General’.

e) Now to the right of the ‘Project property’ window, select the property ‘Additional Library directories’ and add the path of Boost C++ Library directory.

(Example: ‘C:\Program Files\boost\boost_1_38\lib’).

f) Finally click ‘Apply’ and ‘Ok’.

III) ‘Build’ and ‘Run’ your application.

Microsoft Pre-defined macros

_MSC_VER

This is the predefined macro, which identifies the Micro

Soft Compiler VERsion. It comprises of the major and minor number components of the compiler’s version number.

Open your Visual studio Command Prompt and type in “cl/” and hit enter. The output in my system is shown below

.

So, the VC++ compiler version of my system is 15.00.21022.08. In this period delimited version number, the major number corresponds to the first component , 15 and the minor number corresponds to the second component, 00. So for Visual studio 2008, the _MSC_VER macro evaluates to 1500.

Below are a couple of examples of the usage of _MSC_VER macro in programming.

Example1:

#ifdef _MSC_VER

//if it is any version of MicroSoft Compiler, the below main() function

// is executed. Else this portion of code will be inactive.

int main(int argc, char* argv[])

{

//some come

return 0;

}

#else

//if it is any other compiler other than MicroSoft, the below main()

//function is executed. Else this portion of code will be inactive.

int main(int argc, char* argv[])

{

//some come

return 0;

}

#endif

In the above code snippet, it is shown that it has two ‘main()’ functions. But out of these two, at any point, only one will be active and the other is totally inactive. The compiler only identifies the main() function relevant to it. There by this does not result in any compiler error.

Example2:

#if (_MSC_VER >= 1400)

//VC 8.0: Executes this part of the code if the Compiler is VC 8.0

// and above.

#elseif (_MSC_VER >= 1310)

// VC 7.1: Executes this part of the code if the Compiler is VC 7.1.

#elseif (_MSC_VER >= 1300)

// VC 7.0: Executes this part of the code if the Compiler is VC 7.0.

#else

// VC 6.0: Executes this part of the code if the Compiler is VC 6.0.

#endif

In the above example a distinction is made between the various versions of Microsoft compiler. So based on the compiler version that part of the code executes and not all.

Thursday, December 25, 2008

Need for Service Oriented Architechture

Need for integrating an existing business model with new business model: Upgrading the existing business model is a need to adapt to the new customer bases and business partners. Sharing the IT system with another organization is the new trend in business. A practical example could be any online auction sites like the ebay where other third party organizations will register and try to sell their products their by increasing their customer base. In this direction SOA offers a cost effective solution. Legacy systems developed based on a earlier business model might need to be upgraded in order to integrate with the systems developed with new business models. The complexity of this whole process is the biggest challenge for the organizations.

Need for reusability: SOA implements functionalities as services. Each service describes a unique functionality. Organizations IT system is composed of a collection of these services, each one of which can evolve and change.This can be better explained with the following example. Assume there is an iphone for auction. This iphone could be available for auction either through ‘ebay’ or ‘sedo’ or ‘bidz’ or any other auction sites. When users click on this iphone link through any of these auctioning sites, in all scenarios it has to be redirected to the same web page which gives the details of the auction. This single web page which describes the product can be implemented as a service. Here the single web page service is used by multiple auction sites.

Need for Agility:   The ability to adapt rapidly, and taking advantage of change. For example, when a new opportunity arrives (e.g., a new product offering) or a business condition changes (e.g., a merger), companies need technology solutions to support this changing environment. By service enabling systems – grafting an XML and Web services interface onto existing applications – executives can access data that they need to make decisions more quickly, and firms can service their customers more effectively than before.

Efficiency:  Leveraging existing resources as much as possible. It is financial burden for the organization to reinvest time and money to recreate existing software, whether decades-old mainframe, 10-year-old client/server, or two-year-old Internet computing applications. By service-enabling these systems, companies can keep them in place but make it easier to access them or integrate them with other applications. This is achieved, where SOA provides an interface for all the systems, suitable for communication with other systems involved in the process. SOA can even create new solutions by combining existing service-enabled applications into more comprehensive, multiservice solutions called composite applications

Terminologies

Legacy system: is an old computer system or application program that continues to be used because the user does not want to replace or redesign it.

Business model: is a conceptual tool that contains a big set of elements and their relationships and allows expressing the business logic of a specific firm.

Also, a business model is simply a working description that includes the general details about the operations of a business. 

Customer base: is the group of current clients and consumers that a business serves.