190 likes | 237 Views
Learn how to control class initialization and destruction in C++, including Constructor and Destructor usage, Operator Overloading, Interface & Implementation strategies, and more. Deep dive into member function and stand-alone function overloading techniques.
E N D
Constructors & Destructors Controlling initialization & destruction
Operator Overloading • Most operators in C++ can be overloaded • Two ways: • Member function of user defined class • Non-member "stand alone" function • Any operator overloading has to involve a user-defined class object • Has to be at least one operand that is not built-in • Most operators are binary (i.e. the have a left and a right-hand side), and the expression
Operator Overloading • x op y can be defined either • Stand-alone function call • operatorop(x,y); • Member-function call for x: • x.operatorop(y); • If define overloaded operator as member function, it must be member function of left-hand-side object
Interface & Implementation • We want to limit access to data members • Done with private keyword • We want to separate interface from implementation • Constructors automatically called when new object created • Destructors automatically called when object destroyed
Creation • Objects are created in a few ways • double x; • Creates an object of type double • C++ provides mechanism to control what happens when user defined classes are created in statement like above • Constructor
Constructors • Same name as class • No return type (not even void!) • Can be overloaded • Same name, differ by arguments they take • One with no arguments is “default” constructor
Example int main(){ ToD x, y; return 0;} class ToD{ private: int h, m; bool PM; public: ToD(){ cout << "ToD object created!" << endl; }}; What’s on the screen when the program runs?
Use?(besides cheesy messages) • Initialization • Sometimes objects need to have values or perform some operation before they can be used
Isolating Implementation • User can’t manipulate values • User doesn’t need to do anything to initialize • User can’t put object in invalid state
Destructors • Only one per class • Class name with ~ in front • Doesn’t take any arguments • Controls what happens when object destroyed • Called automatically
Destructor Example class Silly{ private: string name; public: Silly(){ cout <<"A silly object is born!"<< endl; } ~Silly(){ cout <<"Silly object "<<name<<" dies!"<< endl; }}; int main(){ Silly *p; if (1>0){ Silly first; first.name = “Tom"; p = new Silly[2]; p[0].name = "John"; p[1].name = “Sara"; } Silly last; last.name = “Tom Jr"; delete [] p; return 0;}
Use? • When is destructor useful? • Executed when object destroyed • Can do anything, but interesting when deallocate memory • Want to delete items created using new to free up memory
Destructor Example /** DEFINITION OF CLASS NODE **/ class Node { public: int data; Node *next; Node(int val, Node* p) { data = val; next = p; } }; List::~List() { while(head != 0) { Node *p = head; head = head->next; delete p; } }
Letting the User Define • What about letting the user choose initialization values? • Example: Point A, B, C;A.x = 2.4;A.y = -0.5;B.x = 0.0;B.y = 3.3;C.x = (A.x + B.x)/2;C.y = (A.y + B.y)/2;
Wouldn’t It Be Nice? Point A(2.4,-0.5), B(0.0,3.3);Point C((A.x + B.x)/2,(A.y + B.y)/2); • Constructors make this possible
To the point (class) Class Point{ public: double x, y; Point() { x = y = 0; } Point(double a) { x = a; y = 0; } Point(double a, double b) { x = a; y = b; }};
Calling Constructors • Called three ways • Previously mentioned • ex. Point p; • Using new Operator • ex. Point *p = new Point(3.3,7.1); • As function that returns object • Point(3.3,7.1).magnitude(); Class Point{public: double x, y; Point(double a, double b) { x = a; y = b; } double magnitude() { return sqrt(x*x + y*y); }};
Default Arguments • In any function prototype, can follow name of parameter with default value Class Point{ public: double x, y; Point(double a = 0, double b = 0) { x = a; y = b; }};