Download presentation
Presentation is loading. Please wait.
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 &vec) { for (std::vector ::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 &vec) { std::vector ::iterator iter = vec.begin(); while (iter != vec.end()){ if (*iter % 2 == 0) iter++; else iter = vec.erase(iter); } int main(){ std::vector vec; while(std::cin){ int i; //assume stdin holds only integers! std::cin >> i; vec.push_back(i); } clean_odd(vec); for (std::vector ::iterator iter = vec.begin(); iter != vec.end(); ++iter) std::cout << *iter << std::endl; return 0; }
4
int main(){ std::map stringCounts; std::string str; while( std::cin >> str ){ std::map ::iterator found = stringCounts.find(str); if (found != stringCounts.end()) found->second++; else stringCounts.insert(std::make_pair(str, 1)); } std::map ::iterator iter; for( iter = stringCounts.begin(); iter != stringCounts.end(); ++iter) { std::cout first << ", count: " 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, 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 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 std::string to_string(const T& t){ std::ostringstream o; o << t; return o.str(); } //usage example: int main(){ std::vector 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 1.// THE DECLARATION FILE OF THE CLASS POINT (Point.h) 2. class Point 3. { 4. public: 5. Point(); 6. Point(double xval, double yval); 7. void move(double dx, double dy); 8. double getX() const; 9. double getY() const; 10. private: 11. double _x; 12. double _y; 13. };
8
C++ simple class example 1.// THE IMPLEMENTATION FILE OF CLASS POINT (Point.cpp) 2.#include "Point.h" 3.Point::Point():_x(0), _y(0){ } 4.Point::Point(double xval, double yval):_x(xval),_y(yval){ } 5.void Point::move(double dx, double dy) { 6. _x = _x + dx; 7. _y = _y + dy; 8.} 9.double Point::getX() const { 10. return _x; 11.} 12.double Point::getY() const { 13. return _y; 14.}
9
C++ simple class example Use example 1.#include 2.#include “ point.h ” 3.int main( ){ 4. Point p(0,0); 5. //Point p; 6. p.move(10,15); 7. const Point p2(20,12); 8. std::cout << p2.getx() << std::endl; 9. std::cout << p2.gety() << std::endl; 10. // p2.move(1,1); compilation error since move is no t declared const 11.}
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 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. Example: Circle::Circle(): _center(0,0), _radius(1) {}
12
Inheritance Syntax: class Derived : public Base { }; #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 1.class Point{.....} 2.int main( ){ 3. Point *p1=new Point(0,0); 4. Point p2(0,0); 5. p1->getX(); 6. (*p1).getX(); 7. p2.getX(); 8. (&p2)->getX(); 9.}
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: 1. A virtual destructor 2. A copy constructor 3. operator= (assignment)
16
Linked List Example Link data_ next_ List head_ data_ next_ data_ next_
17
Link 1.class Link { 2. private: 3. Link* next_; 4. std::string data_; 5. public: 6. Link(const std::string& data, Link* link); 7. Link(const Link& aLink); //copy constructor 8. virtual ~Link(); // destructor 9. void setNext(Link* link); 10. Link* getNext() const; 11. const std::string& getData() const; 12.};
18
1.Link::Link(const std::string& data, Link* link) : data_(data) { 2. setNext(link); 3.} 4.void Link::setNext(Link* link) { 5. next_=link; 6.} 7.Link* Link::getNext() const { 8. return next_; 9.} 10.const std::string& Link::getData() const { 11. return data_; 12.} 13.Link::~Link() { } \\destructor 14.Link::Link(const Link& aLink) { \\copy constructor 15. data_=aLink.getData(); 16. next_=0; 17.} Link
19
List 1.class List { 2. private: 3. Link* head_; 4. Link* copy() const; 5. void clear(); 6. 7. public: 8. List(); 9. const Link* getHead() const; 10. void insertData(const std::string& data); 11. void removeFirst(); 12. 13. List(const List& aList); 14. virtual ~List(); 15. List& operator=(const List &L); 16.};
20
1.List::List() : head_(0) { } 2.const Link* List::getHead() const{ 3. return head_; 4.} 5.void List::insertData(const std::string& data){ 6. head_ = new Link(data, head_); 7.} 8.void List::removeFirst(){ 9. if (0 != head_) { 10. Link* tmp = head_; 11. head_ = head_->getNext(); 12. delete tmp; 13. } 14.} 15.List::~List() { 16. clear(); 17.} 18.void List::clear(){ 19. while (0 != head_) { 20. removeFirst(); 21. } 22.}
21
23.Link* List::copy() const { 24. if (0 == getHead()) return 0; 25. else { 26. Link *head = new Link(*getHead()); 27. Link *next = head; 28. for (Link *origPtr = getHead()->getNext(); 0 != origPtr; 29. origPtr = origPtr->getNext()) { 30. next->setNext(new Link(*origPtr)); 31. next = next->getNext(); 32. } 33. return head; 34. } } 35.List::List(const List &aList){ 36. head_ = aList.copy(); 37.} 38.List & List::operator=(const List &L) { 39. if (this == &L) 40. return *this; 41. clear(); 42. head_ = L.copy(); 43. return *this; 44.}
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 1.void f(List L) { 2. List *p = new List(); 3. while (...) { 4. List L1; 5.... 6. } 7. delete p; 8. } Is a destructor function of a reference parameter called at the end of the function? No!
24
1./** 2. * Destructor: "deep delete" 3. */ 4. List::~List() { 5. clear(); 6. } 7.void List::removeFirst() 8.{ 9. if (0 != head_) { 10. Link* tmp = head_; 11. head_ = head_->getNext(); 12. delete tmp; 13. } 14.} 15. void List::clear(){ 16. while (0 != head_) { 17. removeFirst(); 18. } 19.}
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, 1. Point q(2,2); Point p(0,0); 2. p.moveTo(q); //moveTo(Point point) Returned (by value) as a function result, Declared with initialization from an existing object of the same class. 1.void f(Point p){ 2. Point temp=p; 3. Point temp2(p); 4. …
26
1.List f( List L ); 2.int main() { 3. List L1, L2; 4.... 5. L2 = f( L1 ); // copy constructor called here to copy L1 6.} 7.List f( List L ) { 8. List tmp1 = L; // copy constructor called here to copy L 9. List tmp2(L); // copy constructor called here to copy L 10.... 11. return tmp1; // copy constructor called here 12.} Example
27
Copy Constructor Declaration 1.class List { 2. public: 3. …… 4. List(const List &L);// copy constructor 5.... 6.};
28
Copy Constructor Definition 1.List::List(const List &aList){ 2. head_ = aList.copy(); 3.} 4.Link* List::copy() const { 5. if (0 == getHead()) return 0; 6. else { 7. Link *head = new Link(*getHead()); 8. Link *next = head; 9. for (Link *origPtr = getHead()->getNext(); 10. 0 != origPtr; origPtr = origPtr->getNext()) { 11. next->setNext(new Link(*origPtr)); 12. next = next->getNext(); 13. } 14. return head; 15. } 16.}
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=(const List &L);
30
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 Operator=
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 1.List & List::operator=(const List &L) { 2. if (this == &L) { 3. return *this; 4. } 5. clear(); 6. head_ = L.copy(); 7. return *this; 8.}
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.