1 / 31

System Programming

System Programming. Practical Session 9. C++ classes. Outline STL examples Basic concepts Classes that hold pointers Destructor Copy constructor Operator=. void bad_clean_odd(std::vector<int> &vec) { for (std::vector<int>::iterator iter = vec.begin();

Download Presentation

System Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. System Programming Practical Session 9 C++ classes

  2. Outline • STL examples • Basic concepts • Classes that hold pointers • Destructor • Copy constructor • Operator=

  3. void bad_clean_odd(std::vector<int> &vec) { for (std::vector<int>::iterator iter = vec.begin(); iter != vec.end(); ++iter){ if (*iter % 2 != 0) vec.erase(iter); // @@BAD! After the call to erase, iter is invalid. } } void clean_odd(std::vector<int> &vec) { std::vector<int>::iterator iter = vec.begin(); while (iter != vec.end()){ if (*iter % 2 == 0) iter++; else iter = vec.erase(iter); } } int main(){ std::vector<int> vec; while(std::cin){ int i; //assume stdin holds only integers! std::cin >> i; vec.push_back(i); } clean_odd(vec); for (std::vector<int>::iterator iter = vec.begin(); iter != vec.end(); ++iter) std::cout << *iter << std::endl; return 0; }

  4. int main(){ std::map<std::string,int> stringCounts; std::string str; while( std::cin >> str ){ std::map<std::string,int>::iterator found = stringCounts.find(str); if (found != stringCounts.end()) found->second++; else stringCounts.insert(std::make_pair(str, 1)); } std::map<std::string,int>::iterator iter; for( iter = stringCounts.begin(); iter != stringCounts.end(); ++iter) { std::cout << "word: " << iter->first << ", count: " << iter->second << std::endl; } return 0; }

  5. class Cow{ private:  int _id; public:         Cow(int id): _id(id) {}         int getId() const {return _id;} } // A comparator is a class that implements the operator() // It is passed as a parameter to the priority queue // and used to perform the comparisons among items in the queue. class CowComparator {         public:                 bool operator()(const Cow &x, const Cow &y) {                         // return true if x < y, false otherwise                         return x.getId() < y.getId(); }} int main(){         typedef std::priority_queue<Cow, std::vector<Cow>, CowComparator> PrioQueue;         PrioQueue queue;         while(std::cin) {                 int id;                 // assume stdin holds only ints                 std::cin >> id;                 queue.push(Cow(id));         }         while(! queue.empty()){                 std::cout << queue.top().getId() << std::endl;                 queue.pop(); } }

  6. template <typename T> bool from_string(T& t,                 const std::string& s,                 std::ios_base& (*f)(std::ios_base&) = std::dec){         std::istringstream iss(s);         return !(iss >> f >> t).fail(); } template <typename T> std::string to_string(const T& t){         std::ostringstream o;         o << t;         return o.str(); } //usage example: int main(){         std::vector<int> vec;         std::string line;         while(std::cin >> line){                 int i;                 if (! from_string(i, line)){                         std::cerr << "Please input only ints!!" << std::endl;                         continue;                 }                 vec.push_back(i);         } }

  7. C++ simple class example • //THEDECLARATIONFILEOFTHECLASSPOINT(Point.h) • classPoint • { • public: • Point(); • Point(doublexval,doubleyval); • voidmove(doubledx,doubledy); • doublegetX()const; • doublegetY()const; • private: • double_x; • double_y; • };

  8. C++ simple class example • //THEIMPLEMENTATIONFILEOFCLASSPOINT(Point.cpp) • #include"Point.h" • Point::Point():_x(0),_y(0){} • Point::Point(doublexval,doubleyval):_x(xval),_y(yval){} • voidPoint::move(doubledx,doubledy){ • _x=_x+dx; • _y=_y+dy; • } • doublePoint::getX()const{ • return_x; • } • doublePoint::getY()const{ • return_y; • }

  9. C++ simple class example • Use example • #include<iostream> • #include“point.h” • intmain(){ • Pointp(0,0); • //Point p; • p.move(10,15); • constPointp2(20,12); • std::cout << p2.getx() << std::endl; • std::cout << p2.gety() << std::endl; • //p2.move(1,1);compilationerrorsincemoveisnotdeclaredconst • }

  10. Member Initialization List class Circle{ public: Circle(); Circle(double centerX, double centerY, double radius); ………….. private: Point _center; double _radius; }; Circle::Circle(): _center(0,0) , _radius(1) {} Circle::Circle(double centerX, double centerY, double radius): _center(centerX, centerY) , _radius(radius) {}

  11. Member Initialization List Example: Circle::Circle(): _center(0,0) , _radius(1) {} • Rules • The initial value can be any expression. • The order the initialization happens is according to the order the member variables are declared. • The member initialization list is executed before the body of the constructor. • Not initializing a member via the initialization list means implicitly calling its default constructor • Const members of a class can only be initialized via member initialization list.

  12. Inheritance Syntax: classDerived : publicBase{}; #include “point.h” #include “color.h” // suppose that we have defined class Color… class Pixel : public Point{ Color _color; …… }; Pixel::Pixel(Point point, Color color) : Point(point), _color(color) {} // example of a derived constructor calling the base constructor // Syntax:Derived::Derived(….) : Base(….) {…}

  13. Operator -> Shortcut for accessing members of an object pointed by a pointer. ptr->member is a shortcut for (*ptr).member • classPoint{.....} • intmain(){ • Point*p1=newPoint(0,0); • Pointp2(0,0); • p1->getX(); • (*p1).getX(); • p2.getX(); • (&p2)->getX(); • }

  14. Objects • In C++, object variables hold values, not object references. • When one object is assigned to another, a copy of the actual values is made. • When modifying an object in a function, you must remember to use call by reference. • Two object variables cannot jointly access one object. If you need this effect in C++, then you need to use pointers. • An object variable can only hold values of a particular type. If you want a variable to hold objects from different subclasses, you need to use pointers. • If you want a variable point to either null or to an actual object, then you need to use pointers in C++.

  15. Classes that hold pointers • A class that has a pointer data member should include the following member functions: • A virtual destructor • A copy constructor • operator= (assignment)

  16. Linked List Example Link data_ next_ List head_ data_ next_ data_ next_

  17. Link • classLink{ • private: • Link*next_; • std::stringdata_; • public: • Link(conststd::string&data,Link*link); • Link(constLink&aLink);//copy constructor • virtual~Link();// destructor • voidsetNext(Link*link); • Link*getNext()const; • conststd::string&getData()const; • };

  18. Link • Link::Link(conststd::string&data,Link*link):data_(data){ • setNext(link); • } • voidLink::setNext(Link*link){ • next_=link; • } • Link*Link::getNext()const{ • returnnext_; • } • conststd::string&Link::getData()const{ • returndata_; • } • Link::~Link(){}\\destructor • Link::Link(constLink&aLink){\\copy constructor • data_=aLink.getData(); • next_=0; • }

  19. List • classList{ • private: • Link*head_; • Link*copy()const; • voidclear(); • public: • List(); • constLink*getHead()const; • voidinsertData(conststd::string&data); • voidremoveFirst(); • List(constList&aList); • virtual~List(); • List&operator=(constList&L); • };

  20. List::List():head_(0){ } • constLink*List::getHead()const{ • returnhead_; • } • voidList::insertData(conststd::string&data){ • head_=newLink(data,head_); • } • voidList::removeFirst(){ • if(0!=head_){ • Link*tmp=head_; • head_=head_->getNext(); • deletetmp; • } • } • List::~List(){ • clear(); • } • voidList::clear(){ • while(0!=head_){ • removeFirst(); • } • }

  21. Link*List::copy()const{ • if(0==getHead())return0; • else{ • Link*head=newLink(*getHead()); • Link*next=head; • for(Link*origPtr=getHead()->getNext();0!=origPtr; • origPtr=origPtr->getNext()){ • next->setNext(newLink(*origPtr)); • next=next->getNext(); • } • returnhead; • }} • List::List(constList&aList){ • head_=aList.copy(); • } • List&List::operator=(constList&L){ • if(this==&L) • return*this; • clear(); • head_=L.copy(); • return*this; • }

  22. Destructor • An object's destructor function is called when that object is about to "go away“. • For local variables (objects declared on the stack) and value parameters – When the variable goes out of scope. • For dynamically allocated storage (objects on the heap) – • When the programmer frees the storage using delete.

  23. Destructor • voidf(ListL){ • List*p=newList(); • while(...){ • ListL1; • ... • } • deletep; • } Is a destructor function of a reference parameter called at the end of the function? No!

  24. /** • *Destructor:"deepdelete" • */ • List::~List(){ • clear(); • } • voidList::removeFirst() • { • if(0!=head_){ • Link*tmp=head_; • head_=head_->getNext(); • deletetmp; • } • } • voidList::clear(){ • while(0!=head_){ • removeFirst(); • } • }

  25. Copy Constructor • An object's copy constructor is called (automatically, not by the programmer) when it is created, and needs to be initialized to be a copy of an existing object. • This happens when an object is: • Passed as a value parameter to a function, • Pointq(2,2);Pointp(0,0); • p.moveTo(q);//moveTo(Point point) • Returned (by value) as a function result, • Declared with initialization from an existing object of the same class. • void f(Pointp){ • Pointtemp=p; • Pointtemp2(p); • …

  26. Example • Listf(ListL); • intmain(){ • ListL1,L2; • ... • L2=f(L1);//copyconstructorcalledheretocopyL1 • } • Listf(ListL){ • Listtmp1=L;//copyconstructorcalledheretocopyL • Listtmp2(L);//copyconstructorcalledheretocopyL • ... • returntmp1;//copyconstructorcalledhere • }

  27. Copy Constructor Declaration • classList{ • public: • …… • List(constList&L);//copyconstructor • ... • };

  28. Copy Constructor Definition • List::List(constList&aList){ • head_=aList.copy(); • } • Link*List::copy()const{ • if(0==getHead())return0; • else{ • Link*head=newLink(*getHead()); • Link*next=head; • for(Link*origPtr=getHead()->getNext(); • 0!=origPtr;origPtr=origPtr->getNext()){ • next->setNext(newLink(*origPtr)); • next=next->getNext(); • } • returnhead; • } • }

  29. Operator= • By default, class assignment is just a field-by-field assignment • If a class includes pointer fields, the default assignment operator causes aliasing which lead to trouble! Solution: overload operator= to perform deep copy. Syntax: List&operator=(constList&L);

  30. Operator= • Note that operator= differs from the copy constructor in three important ways: • The object being assigned to has already been initialized; therefore, if it has a pointer field, the storage pointed to must be freed to prevent a storage leak. • It is possible for a programmer to assign from a variable into itself; for example: L1 = L1. The operator= code must check for this case, and do nothing. • The operator= code must return a value

  31. Definition of operator= • It should always include the following 4 sections: • check assignment to self • clear existing data members • copy data member from other • return this • List&List::operator=(constList&L){ • if(this==&L){ • return*this; • } • clear(); • head_=L.copy(); • return*this; • }

More Related