shallow copy 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 or overload the assignment operator.


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.


Example:
class A
{
int i;
public:
A()
{
i=0;
}
void Set()
{
i=20;
}
void display()
{

cout < <>

}

int main()
{
A a,b;
a.Set();//change i to 20
b=a;
b.display(); //this displays the value of i as 20
}
by default here the compiler generates the assignment operator for these objects.

object 'a' is copied into object 'b' . so object 'b' data member 'i' value will same as object 'a' data member 'i' value.

so the output of this program is 20. becoz object 'a' has changed the value of 'i' data member to 20.

what happens if the class A has a pointer *ptr whose memory is created dynamically.

class A

{

char *ptr;

public: A()

{

ptr=NULL;

}

void Set()

{
ptr=new char[5];
strcpy(ptr,"hai");

}

void display()
{
cout < <>

}

void erase()

{

delete []ptr;

}
};

int main()
{

A a;
a.Set();//change i to 20
A b;
b=a;
a.erase();
b.display(); //nothin will be displayed as the memory is erased by a;
system("pause");
return 0;

}

then if we copy object 'a' into object 'b'. pointer(ptr) of object 'a' will get copied to object 'b's ptr but not the value pointed by pointer ptr of object 'a'.

object 'b' s ptr and object 'a's ptr will be pointing to same memory. suppose if object 'a' deletes the its pointer, then the object 'b' will be pointing to the memory which is deleted by 'a' object, so object 'b's ptr will be dangling. I

n this case we go for deep copy. so whenever class has data members which are allocated memory dynamically then we should go for deep copy. deep copy copies the values pointed by pointers but not the pointers.

A class that requires deep copies will generally need:

i )a destructor to delete the dynamically allocated memory.
ii) a copy constructor to make a copy of the dynamically allocated memory.
iii) an overloaded assignment operator to make a copy of the dynamically allocated memory.

Example using the overloaded assignment operator

class A
{
char *ptr;
public: A()
{
ptr=NULL;
}
void Set()
{

ptr=new char[5];

strcpy(ptr,"hai");
}

void display()
{

cout < < ptr;

}
void operator = (const A& a)
{

if(this != &a)
{
ptr=new char[5];

strcpy(ptr,a.ptr);
}
}
void erase()
{
delete []ptr;
}
};
int main()
{
A a;
a.Set();
A b;
b=a;

//invokes overloaded = operator , so creates new memory for b.ptr instead of pointing to //same memory of a.ptr

a.erase();


b.display(); //this displays "hai" becoz memory is not destroyed

system("pause");
return 0;
}
Prev page



function overloading

  1. Allows more than one function to share the same name.
  2. Overloaded function must have a unique signature in either the number or types of their arguments.
  3. Relieves the user of a library from having to remember function names that perform identical actions.

    The return type of a function is ignored while determining overloaded instances

Signatures are different in either the types or number of their arguments.
These instances are considered to be overloaded.

int func(int,int);
int func(int,int,int);
double func(double,double);


The following attempt to overload Func_t() is erroneous.

void Func_1(int);
void Func_!(int&);
void Func_1(const int);

Argument matching rules.

1.Exact match and trivial conversions.
2.Match using promotions.
3.Match using standard conversions.
4.Match using user-defined conversions.

Rule 1. Exact match and trivial conversions
exact match scenario

void Disp(char);
void Disp(int);
void Disp(int&,char&);
void Disp(const char,const int);

int v = 13;
char c = ‘v’;
Disp(v); //will invoke Disp(int)
Disp( c ); //will invoke Disp(char)


Trivial conversions.
t to t&
t& to t
t[ ] to t*
t to const t
F(arg-list) to (*F)(arg-list)

void Disp(char);
void Disp(int);
void Disp(int&,char&);
void Disp(const char,const int);
int v = 13;
char c = ‘v’;
Disp(c,v); //will invoke Disp(const char , const int)
Disp(v,c); //will invoke Disp(int &, char&)

Rule 2. Match using promotions


A char, short int can be promoted to an int.
A float can be promoted to a double.
void Disp(int);
void Disp(double);
char c;
short int s;
float f;
Disp( c) ; // will invoke Disp(int)
Disp( s); // will invoke Disp(int)
Disp( f); // will invoke Disp( double)


Rule 3. Using standard conversion
Uses standard type conversion between one primitive type to another primitive type.
Possible loss of data due to conversion.
void Disp(double);
void Disp( void *);
int v;
char *s;
Disp(v); //Disp(double);
Disp(s); //Disp(void *);

GDB

GDB - Gnome debugger

Many developers may be fed up with fixing the logical errors in programs which causes core dump etc.

Gnome debugger(GDB) is useful to debug the C++ programs. Its used to analyse the core files also. core is the state of memory at specif time caused by program crash.

Lets see this program which causes core dump.

debugging Sample program with GDB
Note: all programs here assume that necessary header files are included.

#include"iostream"
using namespace std;
void func();
int main()
{

func();
return 1;
}
void func()
{
char *p;
strcpy(p,"hello,world");
cout < <>$g++ -g prog.cpp –o prog.o
$ ./prog.o
u will get output like this

Program received signal SIGSEGV, Segmentation fault core dumped .

Core file will be created as core.pid where pid is process id.
Suppose core.1431 gets created here

Note: If core file is not created then check core file size using

$ulimit –c
if it gives 0 , then core files cant be created. So increase the size by giving the

$ulimit –c unlimited

use the command $gdb 'prog_name' 'core_filename' .

here executable is prog.o

$gdb prog.o core.1431

Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
Cannot access memory at address 0xb7600744
#0 0xb743a9b6 in ?? ()

(gdb) run
Starting program: /home/edarav/plusplus/a.out
starting the func Program received signal SIGSEGV, Segmentation fault.0xb743a9b6 in strcpy () from /lib/tls/libc.so.6

the last few lines say that core dumped has come from strcpy in our code. we didnt allocated any space for char *p and we re trying to write into that memory. so the *p has to be initialised with enough memory.

Valgrind - memory leak and memory corruption detector

Valgrind tool is the memory mis management detector. it can detect

1) memory leaks
2) un initialised memory
3)Mismatched use of malloc/new/new [] vs free/delete/delete []
4) Overlapping src and dst pointers in memcpy() and related functions
5)reading or writing from/to pointers after deleting or freeing that pointer etc.

valgrind is wrapper of many tools. among them lets have a look at memcheck tool.

how to use valgrind ?

$valgrind --tool= tool_name --leakcheck= yes executable(ex: a.out)

by default the tool_name will be 'memcheck'


what is a memory leak?
when we allocate memory dynamically (at run time) , and if we dont free it after use, until the termination of program that memory cannot be re-gained. this is called memoy leak.

see the following program prog1.cpp which creates two pointers p and s at runtime on heap. we freed the memory pointed by p, but we didnt freed the memory pointed by s. so the memory pointed by s will not be re used until termination of program.

lets use the valgrind tool to detect the memory leak.



#include"iostream"
using namespace std;
int main()
{
char *p= new char[10];
delete []p;
char *s=new char[20];
return 1;
}

$g++ -g prog.cpp

$valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./a.out

always the first column will be pid of your process.

==13993== Memcheck, a memory error detector.
==13993== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==13993== Using LibVEX rev 1732, a library for dynamic binary translation
.==13993== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==13993== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==13993== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==13993== For more details, rerun with: -v
==13993====
13993====
13993== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 17 from 1)
==13993== malloc/free: in use at exit: 20 bytes in 1 blocks
.==13993== malloc/free: 2 allocs, 1 frees, 30 bytes allocated.
==13993== For counts of detected errors, rerun with: -v
==13993== searching for pointers to 1 not-freed blocks.
==13993== checked 104,344 bytes.
==13993
====13993== 20 bytes in 1 blocks are definitely lost in loss record 1 of 1
==13993== at 0x401B085: operator new[](unsigned) (vg_replace_malloc.c:195) ==13993== by 0x8048595: main (in /home/edarav/plusplus/a.out)
==13993
====13993== LEAK SUMMARY:
==13993== definitely lost: 20 bytes in 1 blocks.
==13993== possibly lost: 0 bytes in 0 blocks.
==13993== still reachable: 0 bytes in 0 blocks.
==13993== suppressed: 0 bytes in 0 blocks.

the bold lines in LEAK SUMMARY will give you how much memory was lost . here we lost 20 bytes.

In our c++ program above we allocated 20 bytes for char *s and we didnt free it. so the report shows those 20 bytes. like wise valgrind memcheck tool can also detect the un initialsed memory.

Common valgrind options

Option : --num-callers=number
Purpose : Determines the number of function calls (i.e. depth of stacktrace) to display as part of showing where an error occurs within a program. The default is a measly 4.

Option : --leak-check=yes
Purpose : Enabling leak checking has valgrind search for memory leaks (i.e. allocated memory that has not been released) when the program finished.

Option : --leak-resolution=high
Purpose : An option that should be used when doing leak checking since all other options result in confusing reports.

Option : --show-reachable=yes
Purpose : An option that makes leak checking more helpful by requesting that valgrind report whether pointers to unreleased blocks are still held by the program.

Option : -v
Purpose : Run in more verbose mode.

Option : -fno-inline
Purpose : An option for C++ programs which makes it easier to see the function-call chain.

Option : --gen-suppressions=yes
Purpose : A simple way to generate a suppressions file in order to facilitate ignoring certain errors in future runs of the same code.

Option : --skin=addrcheck
Purpose : (Note that the name of this option has become --tool and has become mandatory for the development release). This selects the specific tool of valgrind that will run. Memcheck (the only tool covered here) is the default.

Option : --logfile=file-basename
Purpose : Record all errors and warnings to file-basename.pidpid

classes

what is the size of this empty class?

class A
{
};

int main()
{
A a;
cout < < sizeof(a);

what is the size of class B here?

class A
{

};
class B:public A
{
};
int main()
{
B b;
cout< < sizeof(b) ; return 0; } the size of B is also a 1. even though B is inherited from class A , which doesnt have data members, class B size will be 1. similarly if any empty class say C, is inherited from empty class B, then the size of class C would be only 1 .

Next Page

Virtual functions

what is a virtual funtion? when it is used!!

C++ virtual function is a member function of a class, whose functionality can be over-ridden in its derived classes. The whole function body can be replaced with a new set of implementation in the derived class.Whenever a program has a C++ virtual function declared, a v-table is constructed for the class. when we wan to select anything based on context at run time then we go for virtual functions.

Example: if we have one GUI application where you scroll mouse over various elements like buttons,links,navigation bar.you want to display some properties when your mouse points to buttons and you want to display other properties when your mouse points to links. so here you want to display the things based on your mouse points to at run time. in these kind of applications we will use virtual functions. In this example we will make display function as virtual.we can see which behaviour is varying and lets make it virtual

what is call-mechanism in late binding?

The v-table consists of addresses to the virtual functions for classes and pointers to the functions from each of the objects of the derived class. Whenever there is a function call made to the c++ virtual function, the v-table is used to resolve to the function address. This is how the Dynamic binding happens during a virtual function call.

Can virtual functions have inline declarations ?

Generally, compilers can't inline a virtual function call if the it's resolved dynamically. Therefore, declaring a virtual member function inline might seem pointless. However, not every call of a virtual function is resolved dynamically; in some cases, the compiler can resolve the call statically, as if the function weren't virtual. In situations like these, the compiler can also inline the call.

For example:

class Base

{

public:

inline virtual int f()

{

return 0;

}

};

int main()

{

Base b;

b.f(); // resolved statically; call can be inlined

}

The invocation of f() is resolved statically because b is not a pointer or a reference. The compiler can also expand the call inline, thereby optimizing the code even further.

Can you Instantiate object for this class?

#include"iostream"

using namespace std;

class A

{

public:virtual ~A()=0

};

int main()

{

A *a=new A();

return 0;

}

NO. destructor is also a member function. here it is pure virtual so the VTABLE is in-complete. we cant create the objects for classes whose VTABLES are incomplete.

Which class member function f1() will be invoked. A or B?

#include"iostream"

using namespace std;

class A

{

public:

virtual void f1()

{

cout < < "this is A class f1()" ;

}

void f2()

{

f1();

}

};

class B:public A

{

public:void f1()

{

cout< < "this is B class f1()" ;

};

int main()

{

A *a=new B();

a->f2();

return 0;

}

Here using the base class ponter we are calling the f2() function which is not virtual. hence A::f2() will be called, but in that body we are calling f1 again which is virtual, so the derived class B::f1() will be invoked

Design patterns

1. Abstract---------------------------------------------------------

The design patterns are useful in the design phase of the object oriented software. Traditionally many experienced designers and architects have found that the some of the design solutions can be reused and named them as patterns. These design patterns make our design more flexible and maintainable so that it is easy to handle new requirements coming in latter stage. This document covers three design patterns. Abstract factory pattern, bridge pattern and facade pattern.

2. Intended Audience------------------------------------------------

For the developers who are involved in object oriented design. To understand the patterns I assume that the developer has aware of inheritance, aggregation, encapsulation and UML class diagram concepts in object oriented paradigm.


3. Motivation
---------------------------------------------------------------

Why to use the Design patterns? Because it is hard to develop reusable software and handling new requirements in software without changing the existing system much

4. Introduction to design patterns----------------------------------

A pattern is a recurring solution to a standard problem. When related patterns are woven together they form a ``language'' that provides a process for the orderly resolution of software development problems. Patterns have a context in which they apply. Clarity of expression makes it easier to see when and why to use certain patterns, as well as when and why not to use these patterns.

Some times we come across the situation where the requirements keep on changing while the project is in design phase or in coding phase, instead of changing the design again and again, we can predict where the changes can be and how to take the step so that we can meet the future requirements with minimal changes in design and in code.

It is ideal that without changing the existing system the additional functionalities can be added. So instead of making major changes in design, let’s keep the changes to be done minimum so that maintenance will not be a nightmare. Patterns help in this scenario.


Let’s discuss some basic object oriented design principles. They are
• Program to an 'interface', not an 'implementation'.
• Favor aggregation over inheritance.
The advantages in using these rules are
• Clients remain unaware of the specific types of objects they use, as long as the object adheres to the interface.
• Clients remain unaware of the classes that implement these objects; clients only know about the abstract class defining the interfaces.
Let’s look at patterns now

BRIDGE PATTERN:
The intent of this pattern is decouple the abstraction with the implementation. Here the abstraction refers to the class and implementation refers to how classes are implemented. Lets look it with an example.

Suppose I had been given a task to draw rectangle using the drawing algorithms DP1 and DP2 say. I was told that when I instantiate the rectangle I know which algorithm should I use.

Let us suppose DP1 implements draw_a_line() for line and draw_a_circle() for circle.
Let us suppose DP2 implements drawline () for line and drawcircle () for circle

Let’s take the abstract class shape and derive rectangle and circle. Now rectangle can use two versions of drawing. So let’s take v1 rectangle and v2 rectangle which uses DP1 and DP2 programs respectively. The same we design for circle class also. Let’s look at design now how it comes.

Click at the picture to enlarge.



V1 rectangle and V1circle uses DP1 class methods and V2 shapes uses DP2 methods.

Let us suppose client has come up with new shape again say triangle, then see how the impact will be. It results in creating other hierarchy called triangle. Again V1Triangle V2Triangle total 3 classes will be created. There will be tight coupling with DP1 and DP2 classes again.

Then again Imagine one more drawing program has come say DP3, then one more concrete class of each shape has to be created. Total it results in 9 classes. So there is need to separate the variations in abstraction with variations in implementation.

This is the intent of bridge pattern
Now lets separate the implementations drawing programs and shapes(rectangles and circle)
Let’s group rectangle and circle together as shape and DP1 and DP2 as Drawing class.

There are 2 basic strategies in creating designs.
1. Find what varies and encapsulate it.
2. Favor aggregation over inheritance.


This is because the implementations can scale independently. So the final design comes like this.

click on image to enlarge



Now the new shapes or new drawing program can be easily added without creating many class hierarchies

Façade Pattern:

Façade pattern is used to simplify the interface of subsystem which is so complex. Some times the client object has to communicate with many other objects. In those cases we will create one simple interface so that client object always requests this interface. This interface in turn based on client request communicates with appropriate object.

Let’s think we designed database API . We have 3 classes.

1) Environment class which is responsible for creating the database environment
And for creating connections
2) Connection class which is responsible in creating the statements
3) Statement class which is responsible for executing queries and returns the
Result set.
4) ResultSet class which is data structure useful for storing the result

Suppose I have one the client who wants to interact with this database and gets the model. First he creates the environment and then requests the connection to Environment class. After getting the connection object using that client will create the statement and executes the query . Finally he gets the result set.
Here the client object is interacting with Environment class, Connection class, Statement class and Resultset class

Client --------------> Environment class

Client ----------------> Connection class

Client------------------> Statement class

If there is any change in these classes the client has to change its behavior. So let’s wrap all these classes into sub system and design one interface which interacts with all these.

Now for binding, for connection, for query the client will interact with this interface only




Now the communication will be between the client and Façade interface. If client wants the connection, he will request the façade interface which in turn requests the Environment class to create the connection. If our subsystem grows in future it’s the only Façade interface class has to be changed.

Façade pattern is useful to reduce the number of objects to which client communicates directly.

Another example of façade pattern in real time scenario is customer call centre. Let’s suppose a financial institute has savings bank, credit card and insurance departments. So the customer calls the customer care and requests the customer care system to get connected to department. The customer care gets the job done for you. Here the customer care is interface for your queries.

Abstract factory pattern:

Abstract factory is used when we want to create family of objects that relate each other for specific cases. For example when dealing with user interfaces the system might use set of objects for one operating system and other set of objects for other operating system. The abstract factory ensures we get the right set of objects for situation.

Lets design the system which to display and print the shapes from database.
To print and display we have to take care of our computers screen resolution, memory and CPU speed. Let’s design for resolution only now.
For high resolution systems lets take high-resolution print driver (HRPD class) and high-resolution display driver (HRDD class). Like wise for low resolution system we will take low resolution print driver and display driver. For these we shall use LRPD and LRDD classes respectively. If we go for simple design using abstract classes and derive the concrete classes the design will be like this.




Here the Application control (ApControl) uses display driver and print driver and gets the appropriate version. This looks fine as of now.

Let’s assume that we need to support a middle resolution system. Then for each Driver classes other instance has to be created. Not only for middle resolution system for any other specific case the DisplayDriver and PrintDriver classes will have one more instance. Assume that like Drivers if some other criteria comes into picture like CPU speed. Then the Apcontrol will have other hierarchy of classes which results in explosion of classes. It will be simple if have system that creates set of objects according to situation and platform. Uniformity is lacking in this system we designed here.

Let’s create the factory which creates appropriate set of objects. Let’s apply the basic principles
1) See what is varying here and encapsulate it. Here the selection of drivers are varying so lets create ResFactory class which consists of these variations
2) Favor aggregation over inheritance. Now the ApControl class just uses Resfactory which contains the variations
3) Design to interfaces not the implementation. The ApControl knows how to ask ResFactory for instantiation of drivers. But it doesn’t know how ResFactoy is creating the objects.


The Resfactory is abstract one and lets create concrete classes LowResFact and HighResFact which creates objects suitable to their platform. Here the LowResFact is responsible in creating the printing and display drivers for low resolution and same case with HighResFact.

Lets Create PrintDriver for the classes of printing drivers and one abstract class DispDriver for display drivers.



Now the client object knows whom to ask for the objects. The Resfactory is the abstract factory which has the methods to create objects. The concrete classes LowResFact and HighResFact will instantiate the objects accordingly. Here the ApControl will ask the ResFactory to create the display drivers and print drivers. The Resfactory has the methods to select the objects to be created accordingly.

Another example of abstract factory pattern is car manufacturing system. Suppose
We have maruthi800 car, maruthi swift, maruthi Zen cars. To prepare the body of the particular car the client object has to request the factory class which selects the parts accordingly to car type and returns them.

Linux

lets discuss some basic commands first
http://techie-builder.blogspot.com/2010/02/some-basic-commands-on-linux.html


what is a shell?
http://techie-builder.blogspot.com/2010/02/what-is-shell-in-linux.html

what is an inode?
http://techie-builder.blogspot.com/2010/02/inode-in-linux.html


what are the runlevels in linux?
http://techie-builder.blogspot.com/2010/02/run-levels-in-linux.html

Boot process in linux after you select the OS label
http://techie-builder.blogspot.com/2010/02/boot-process-in-linux-after-selecting.html


what is cronjob in linux?
http://techie-builder.blogspot.com/2010/02/cron-jobs-in-linux.html





How to put job in background?

http://techie-builder.blogspot.com/2010/02/put-job-in-background.html

how to bring background job to fore ground?
use 'fg' command. fg [pid]

How to put foreground job into background ?
http://techie-builder.blogspot.com/2010/02/put-foreground-job-into-background-on.html


How to enable telnet/FTP services in redhat linux. 
http://techie-builder.blogspot.com/2010/02/enable-telnetftp-services-on-redhat.html


How to duplicate harddisk on Linux
http://techie-builder.blogspot.com/2010/02/duplicate-hardisk-to-other-hard-disk-on.html


Broadcast message on all terminals.
http://techie-builder.blogspot.com/2010/02/broadcast-message-on-all-terminals.html


Display system BIOS details
http://techie-builder.blogspot.com/2010/02/display-system-smbios-hardware.html


Get manual page for a command in linux
http://techie-builder.blogspot.com/2010/02/manual-page-for-commands-in-linux.html


Change system conf on next boot
http://techie-builder.blogspot.com/2010/02/change-system-configuration-on-next.html