what is constructor overloding?whats its need?what is the method of constructor overloding?what r the problems faced during cons. overloading?
OK, although a constructor for a class is a special member function it is still considered a function and like all functions in C++ its name can be overloaded. This is the practice of using a function of the same name but having different types and/or numbers of parameters:
int func( int a );
double func( double a );
int func( int a, int b );
double func( int a ); // _NOT_ ALLOWED
In the above examples we have three declarations of a function func. The first two differ in the type of their parameters, the third in the number of parameters. The fourth example is in fact considered to be equivalent to the first, so is not allowed. This is because in C++ the return type does _not_ form part of the set of types considered for differentiating functions having the same name (i.e. overloaded functions).
Now a class constructor is used to create instances of that class, and is a special (instance) member function having the same name as the class whose types it is to create. If a class has no explicitly defined constructors then the compiler will generate default constructor implementation for the class. These are a default constructor that takes no parameters at all and does nothing, and a copy constructor that creates a new instance from an existing one by copying the bits of the existing instance to the new instance. So even if you define no constructors you have two ways to create a class instance.
Overloading constructors, like overloading other function names, is just the practice of defining more than one constructor for a class, each taking a different set of parameters:
A(); // Default constructor
A( A const & other ); // Copy constructor
Above I have defined a class having explicit declarations for the default and copy constructors. Presumably the implicit implementations are not what are required for class A. Note: the constructor definitions will be assumed to exist elsewhere.
The need for this should be obvious - to allow a class to be created from various parameters (or none at all). For example objects of type A can be created like so:
A an_a; // default constructed
A an_a_copy( an_a ); // copy constructed
What constructors a class should have depends on the class in question. In general if all that is needed are the compiler generated default and copy constructors then do not define any constructors as the compiler may well be able to a more efficient job than the explicit equivalents. However, if you define _any_ constructor then you should define a default constructor if the class requires one as defining any explicit constructors prevents the compiler generating a default constructor for you. This is not true of copy constructors. Note that you require a default constructor if you expect to create built in arrays of objects of the class.
To take an example of a class type that is common, a string class. It would be useful to have a default constructor and a copy constructor. Depending on the implementation we may need to define an explicit copy constructor, and we will almost certainly require an explicit default constructor. So we can create empty strings and copies of strings. It would also be nice to be able to create strings from literals. Two types spring to mind: character literals such as 'a' and string literals such as "a string", or indeed char and char * objects in general. That is two more constructors. A common way to initialise a string is with a number of the same character. This could be another constructor or the create-from-a-character constructor could have a second parameter defining how many of the character the string contains (which could default to 1). Other variations might include constructing from parts of existing strings.
As to the problems there are no specific problems with constructor overloading other than those associated with overloading in general and constructors in general.
Overloading pitfalls are:
The mixing of overloads and default parameter values. The following are equivalent as far as calling them is concerned:
void func( int a );
void func( int a, int b = 1 );
As both can be called with a single int parameter. This applies equally to constructors that mix specific overloads and default parameters.
Another problem occurs when mixing integer and pointer types:
void func( int a );
void func( int * pa );
And the caller passes a literal null pointer value. In C++ 0 converts to a null pointer value and the C NULL definition will map to this value. So the following:
func( NULL );
is the equivalent to:
func( 0 );
So the call to func( NULL ) could be taken as func being passed a zero valued integer or a null pointer value, leading either to the overload of func taking an int being called or to an ambiguity giving a compiler error, depending on your compiler's interpretation of C++. In the case of a constructor it may mean your object is created in the wrong manner.
Another pitfall is when types appear to differ but do not. For example:
typedef int integer32;
void func( int a )
void func( integer32 a )
In the above example integer32 is a type alias for int. When we try to differentiate calls to func on int and the integer32 alias we find the compiler looks through the alias to the underlying type and the second definition of func taking an integer32 looks to the compiler as if it takes an int and it issues an error. In some cases it may not be obvious that such aliases map onto types for which there is already an overloaded function definition. The classic example would be compilers that do not know of wchar_t relying on it being defined as a typedef as it is in C, rather than having wchar_t as a proper built in type, as C++ dictates. If code like the following is compiled by such a compiler it will generate an error (assuming that wchar_t is an alias for unsigned int), but the code should be legal:
void func( unsigned int a )
void func( wchar_t a )
Finally, do not overload too much. Often you can get away with fewer overloads than you think because the compiler will convert similar types from one to another. However this can get in the way: a char to int conversion may not be what you wanted so you may require a specific overload taking a char.
Constructor pitfalls are:
As mentioned above explicitly defining any constructor requires explicitly defining a default constructor if needed.
Defining constructors that take only one parameter allows that constructor to be implicitly used by the compiler to convert from the parameter type to the class type of the constructor. This is OK in many situations, such as converting a string literal to a string class instance. However in many other places it does not make sense. For example a vector (single dimensional array) class that takes an integer type parameter to specify an initial number of elements in the vector object. In this case such an integer type can be implicitly converted to a vector type - which is probably not too useful and will probably hide errors (bugs!). In such cases you have to mark the constructor explicit:
explicit Vector( unsigned int size );
// Explicitly call the Vector::Vector(unsigned int) constructor
// Do stuff with v, fill it up with values etc..
v = 10; // ERROR as Vector::Vector(unsigned int) is explicit.
The above example assumes Vector has a meaningful assignment operator (operator=), which implies it also has a meaningful copy constructor as if one makes sense so does the other. I have not shown either in the parts of the Vector class shown to keep things simple.
Without the 'explicit' qualification on the Vector::Vector(unsigned int) constructor declaration the line with the comment starting ERROR next to it would be legal. In this case 10 would be converted to a new (temporary) Vector by implicitly calling the Vector::Vector(unsigned int) constructor. Although this sounds like it is neat it would cause more errors and bugs. Assuming vector stored integer values it is more likely that v = 10 should have been something like v[index] = 10 and the author forgot the subscript. By adding the 'explicit' qualification to a constructor it prevents the constructor calling it implicitly when we are not looking, i.e. an explicit constructor can only be called when we explicly use it, as in the Vector v(10); line.
Note that this only applies to single parameter constructors as only such constructors can be used to convert from one type instance to another.
Now I only have a few characters left before the 10000 character answer limit so I shall stop here. I hope this is useful to you.