Sie sind auf Seite 1von 74

Chapter-5 constructor

A member function with the same name of class is called constructor and it is used to initialize the data members of that class with a legal initial value.

example
class student { private: int rollno; float marks; public: student() { rollno=0; marks=0.0; } };

Note

Constructor and destructors have no return type , not even void. Whenever an object of the student type will be created (declared), the compiler automatically calls the constructor student::student() for the newly created object.

Need for constructor

A structure or an array in c++ can be initialized at the time of their declaration. struct Student { int rollno; float marks; }; int main( ) { Student s1 = {0 , 0.0}; int a[5] ={1,2,3,4,5}; }

But such initialization does not work for a class because the class members have their associated access specifiers. class Student { int rollno; float marks; . }; int main( ) { Student senior = {0 , 0.0}; // illegal (data members is private) .. }

The private data members are inaccessible by a non-member function . [eg. main( )] There can be an alternative solution to it. class student { int rollno; float marks; public: void init( ) { rollno = 0;

marks = 0.0; } }; int main( ) { student senior; //create an object senior.init( ); // Initialize it }

Here the problem is programmer has to explicitly invoke it, in order to initialize the object. If the programmer forget to invoke init(), in such case, data member will have garbage value and might cause problem in your program. A constructor for the class is needed so that compiler automatically initialize an object as soon as it is created.

Declaration and definition


class X { int i; public: int j , int k; X() { i=j=k=0; } .. };

class X { int i; public: int j, int k; X( ); }; X::X( ) //constructor defined outside { i=j=k=0; }

Note

Constructor can be defined under public, private or protected section. Private/Protected constructor is available to member functions and friend functions. Generally, a constructor should be defined under the public section of the class.

Constructor with arguments


Constructor can also have arguments. class XYZ{ int i; float j; public: XYZ (int a, float b) //with arguments { i = a; j = b; } . };

Creation of objects

Object can be created in two manners XYZ ob1(2, 13.5); XYZ ob2 = XYZ(4, 19.22);

Default constructors

A constructor that accepts no parameter is called the default constructor. X::X() is the default constructor for X since it takes no parameter. XYZ::XYZ(4,3.5) is not a default constructor. If program has no explicit constructor defined, the compiler will supply a default constructor.

The default constructor no arguments The default constructor provided by the compiler does not do anything specific. It initializes data members with garbage values.

class A { int i; public : void getval(void); void prnval(void); .. }; A ob1; // uses default constructor implicitly defined default constructor is a public member of the class.

Parameterized constructors

Parameterized constructor is also called as regular constructors. A constructor that accepts parameters for its invocation is knows as parameterized constructor. Declaring a constructor with arguments hides the default constructor(so we have to define default once again if required).

Constructor with default arguments is equivalent to a default constructor. If your class has two default constructors- one explicit default constructor and one with default arguments, it leads to ambiguity .So its recommended to have one default constructor in a class.

class A { int i; float j; public: A (int a=0, float b = 1000.0); // prototype declaration with default arguments };

A :: A (int a, float b) { i=a; j=b; } int main( ) { A 01(23, 2715.50); // Argument values passed for object 01 A 02; // Takes default argument value. (0, 1000.0) .. }

Significance of default constructors


class Test{ int a; char b; public: Test (int i , char j) { a=i; b=j; } }; int main() { Test Tarray[5]; //error array of objects can not be created because default constructor is not available. Test newobj(31,z);

Default constructor
class Test{ int a; char b; public: Test() { cout<<a1\n; } Test( int i , char j) { a=i; b=j; cout<<c\n } };

int main( ) { Test Tarray[5]; // now no error Test newobj(31, z); }; Output:- a1 a1 a1 a1 a1 c

Invocation of constructor

With parameterized constructor for a class, one must provide initial values as arguments, otherwise, the compiler will report error. class Vrb{ int i; public: float j; char k; Vrb (int a, float b, char c) { int a; j=b; k=c; } };

Vrb obj1; // invalid. One must provide initial values as arguments while object creation otherwise , the compiler will report error.

Two ways of passing initial values:By calling the constructor implicitly (implicit call) By calling the constructor explicitly (explicit call)

Implicit call to constructor


Implicit call, means that the constructor is called even when its name is not been mentioned in the statement. For example:Vrb obj1(13, 11.4, p); // implicit call

This method is also called as shorthand method

Explicit call to the constructor

Explicit call, means that the name of the constructor is explicitly provided to invoke it.

For example:Vrb obj1 = Vrb (13, 11.4 , p); //explicit call

Temporary Instances

The explicit call to a constructor also allows you to create a temporary instance or temporary object. A temporary instance is one that lives in the memory as long as it is being used or referenced in an expression and after that it dies. The temporary instances are deleted when they are no longer referenced.

Example
class Sample{ int i, j; public:Sample(int a , int b) { i=a; j=b;} void print (void) { cout<<i<<j<<\n;} }; void test() { Sample S1(2,5); S1.print(); // data values of s1 printed Sample(4,9).print(); // temporary sample instance }

In this example , Sample(4,9) is an anonymous temporary instance and lives in the memory as long the statement Sample(4,9).print(); is executing. The compiler deletes it after use.

Constructor and primitive type


Even primitive types have constructor. Like objects we have initial values for variables also. int a,b,c; //default constructor used int i(3) , float j(4.5) //i,j initialized with 3 and 4.5

Constructors are used in the following situations

When a new operator is used: (the new is a dynamic memory allocation operator, which is used to create objects/variables at run time) Test *x; // new operator is used with pointer x= new Test // a new object of test type is created during runtime

When the associated type is used in a definition: void func( ) Test f; // constructor called to allocate f

{ }

Copy constructor

Copy constructor is used when we want to initialize an object with the values of another object of same type.

For example, Sample S1; // default constructor used Sample S2=S1; // copy constructor used

In the above code, for the second statement, the compiler will copy the instance s1 to s2 member by member . If you have not defined a copy constructor, the compiler automatically creates it and it is public. You can define your own copy constructor also. A copy constructor takes a reference to an object of the same class an argument.

class X { int a; int b; public: X(int i, int j) { a=i; b=j; } X(X & s) { a=s.a; b=s.b; } };

Void main() { X X1(4,5); //invokes parameterized constructor X X2(X1); //x1 is copied to x2 copy constructor is
invoked

X X3=X1; //X1 }

is copied to X3(copy constructor is called)

Syntax of copy constructor is


classname(classname reference objectname)

{ . .. } The process of initialization through a copy constructor is known as copy initialization.

main() { X X1(4,5), X2(10,20); X2=X1; } Statement X2=X1, will not call the copy constructor. But this statement is valid. It assigns the values of X1 to X2 member by member.

When is a copy constructor called


When an object is declared and initialized with another object. class X {int a,b; public: X(int i, int j) { a=i; b=j;} }; void main() { X X1(10,20); X X2=X1; }

When an object is passed to a function by value [Here the contents of actual argument is getting copied to formal argument] f1(X1) //actual parameter f1(X X7) //formal parameter {.. } //function can be member function or non member function

When a function return an object

Test func( ) { return myobj; // constructor called to make a copy of the object }

Why argument to a copy constructor is passed by reference? If we pass argument by reference the reference does not need separate memory locations. So by using reference memory is saved . [in C++ it is must that copy constructor must pass argument by reference]

Order of constructor invocation


The constructs are invoked in the same order in which the objects are created. Ex:-Sample s1, s2, s3; If class contains objects of another classes as its data member , the constructors for members are invoked first and then only, the constructor for the containing class is invoked.

#include<iostream.h> #include<conio.h> class Sub{ int days; public: Sub() {..} }; class Stud{ int rollno; public: Stud() {..} };

class Admission { Stud st1; Sub su1; public: Admission() {} }; int main() { Admission adm; }

The above program creates an object adm of a class Admission that contains two objects of classes Sub and Stud as its members. The order of invoking constructors are, Constructor of Sub Constructor of Stud Constructor of Admission

Note

Remember Admission is not responsible for initializing its member object st1,sb1. Each class is responsible for initializing its own objects. Thus st1 is initialized by Stud and sb1 is initialized by Sub

Dynamic initialization of objects

The dynamic initialization means that the initial values may be provided during runtime. Even class objects can be initialized dynamically. i.e. with the value provided at runtime. class sample{ int rollno; float marks; public:

sample (int a , float b) { rollno = a; marks = b; } sample (sample &s) //copy constructor { rollno = s.rollno; marks = s.marks; cout<<\n copy constructor \n; } };

int main( ) { int x; float y; cout<<Enter rollno of student:; cin>>x; cout<<Enter the marks; cin>>y; sample s1(x,y);//dynamic initialization }

The benefits of dynamic initialization is that it provides the flexibility of assigning initial values at run time.

Initialization of constructor and reference members


struct Sname { char fname[25]; char lname[25]; } s1; class Test { int a, b; const int max; //cant initialize constant here sname & name; //cant initialize reference here public: Test( ) { a=0; b=10; max=300; //will produce error name s2; //will produce error } };

Member initialization
struct Sname { char fname[25]; char lname[25]; } s1; class Test { int a, b; const int max; //cant initialize constant here Sname & name; //cant initialize reference here public: Test( ) : max(300), name(s2) // initialized through member initialization { a=0; b=10; } };

Member initialization
Mem-initialization lists are especially used in following four cases: Initialization of const members Initialization of reference members Invoking base class constructor Initialization of member objects last 2 will be discussed in Inheritance chapter

Constructor overloading

Just like any other function, the constructor of a class may also be overloaded so that even with different number and type of initial values an object may still be initialized.

Default arguments versus overloading


Using default arguments gives appearance of overloading, because the function may be called with an optional number of arguments. For instance float amount (float principal, int time =2 ,float rate =0.08) Using overloading in place of default arguments is more beneficial.

Special characteristics of constructor


Constructor functions are invoked automatically when the objects are created. If a class has a constructor, each object of that class will be initialized before any use is made of the object. Constructor functions obey the usual access rule. That is, private and protected constructors are available only for the member and friend functions. However the scope of public constructor is same as the scope of the class.

Only the functions that have access to the constructor of a class, can create an object of the class. No return type can be specified for a constructor. They cannot be inherited, though a derived class can call the base class constructor. A constructor may not be static.

Default constructors and copy constructors are generated wherever needed. Compiler generated constructors are public. An object of a class with a constructor cannot be a member of a union. Member functions may be called from within a constructor. A constructor can be used explicitly to create new objects of its class type, using the syntax class-name (expression-list) For ex:-Sample obj1=Sample(13,22.42);

Destructors
A destructor is also a member function whose name is the same as the class name but preceded by tilted(~). Destructor is a NOT constructor A destructor takes no arguments, and no return types.

class Sample { int i , j; public: Sample(int a, int b) { i=a; j=b;} ~Sample( ) {cout<<Destructor at work\n; } . };

int main( ) { Sample s1(3 ,4); //automatically s1 is destructed at the end of the block using destructor ~Sample( ) }

Need for a destructor

During the construction of the object by invoking constructor, resources may be allocated for use .These allocated resource are deallocated when the object is destroyed. A destructor volunteers here for this task and performs all clean-up tasks like closing a file, deallocating memory area automatically. Therefore destructor is equally important as a constructor.

Declaration and definition

A destructor being a member function obeys the usual access rules for a member function. That is , if defined as a private or protected member function , it becomes available only for member functions and only these can be create, used, and destroy objects of this class type.

Public destructor - its objects can be created, used, and destroyed by any function. Only the function having access to a constructor and destructor of a class, can define object of this class types otherwise the compiler reports an error.

class Sample { int i , int j; ~Sample( ) { cout<<Destructing ; } //private destructor public: Sample( ){ i=0; j=0 ; } //constructor void memb1(void); void memb2(void); void Abc();

void Sample :: mem1(void) { Sample s1; // valid } void Sample :: mem2(void) { Sample s1; // valid } void Abc(void) { Sample s1; // valid. Abc() is a friend function }

void main( ) { Sample s4; // invalid. main() is a nonmember function }

Note

If you fail to define destructor for a class, the compiler automatically generates one, the default constructor. dtor is typical abbreviation for destructors. If more than one object is being destructed, the destructors are invoked in the reverse order in which the constructors are called.

{ Sample s1; //s1 constructor is invoked Sample s2; //s2 constructor is invoked Sample s3; //s3 constructor is invoked .. //s3 destructed .. //s2 destructed //s1 destructed }

Characteristics of destructors

Destructor function are invoked automatically when the objects are destroyed. You can have only one destructor for a class. In other words, destructors cant be overloaded. If a class has a destructor, each object of that class will be deinitialized before the object goes out of scope. Deconstructor functions also obey the usual access rules as other member functions do.

No argument can be provided to a destructor not even return type. They cannot be inherited. They may not be static. It is not possible to take the address of a destructor. Member function may be called from within a destructor. An object of a class with a destructor cannot be a member of a union.

end

Das könnte Ihnen auch gefallen