#include<iostream.h>
#include<conio.h>
class Add // Declaration of class
{
private: // Data member
int a,b;
Public:
Add( ) // Default constructor
{
a=0;
b=0;
}
Add(int x) // constructor
{
a=x;
b=x;
}
Add(int x,int y) // Parameterized constructor
{
a=x;
b=y;
}
void display() // Data Member Function
{
int z;
z=a+b;
cout <<"\n sum is ="<<z;
}
};
main( )
{
clrscr( );
int p,q;
cout<<"Enter Numbers =";
cin>>p>>q;
add a1;
add a2(p);
add a3 (p,q);
a1.display( );
a2.display( );
a3.display( );
getch( );
}
-------------------------------------------------------------------------
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:
class A
{
public:
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 )
{
// ...
}