1 / 36

The Object class hierarchy

The Object class hierarchy. ADT hierarchy. Object. Container. Stack. StackAsArray . StackAsLinkedList . Queue. QueueAsArray . QueueAsLinkedList . PriorityQueue. Graph. Tree. ADT hierarchy (con’t). Object. Searchable Container. Container. SearchTree. BST. List.

cricket
Download Presentation

The Object class hierarchy

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. The Object class hierarchy

  2. ADT hierarchy Object Container Stack StackAsArray StackAsLinkedList Queue QueueAsArray QueueAsLinkedList PriorityQueue Graph Tree

  3. ADT hierarchy (con’t) Object Searchable Container Container SearchTree BST List InOrderList ListAsArray ListAsLinked HashTable ChainedHT

  4. Abstract classes • specify only an interface, no implementation • cannot be used to instantiate objects • are used to build other classes through inheritance • intended as the base class from which others are derived • often contain ‘pure virtual member functions’ • contain only interface, no implementation • the base class interface allows you to access the derived class member functions • allows for high levels of polymorphism

  5. Concrete classes • Derived from base classes through inheritance • Can be used to create many different implementations of an ADT • sub ADTs

  6. Object class hierarchy Object In object-oriented languages, all ADTs can be seen to be derived from a single ancestor - the Object ADT. Stored in this class definition would be all the essential qualities that any object must have. But what might the member functions, etc. be?

  7. Object class members Object 1. We will need to compare any two variables of the same derived class. (compareto) 2. We will need to determine whether an object contains anything. (isNull) 3. We will need to compare any two variables that are derived from the Object class. (compare) 4. We will need to send the contents of an object into an output stream for printing (put) 5. We will need the normal overloaded operators

  8. Object class members Object class Object { protected: virtual int CompareTo (Object const&) const = 0; public: virtual ~Object(); virtual bool IsNull() const; virtual int Compare(Object const&) const; virtual void Put(ostream&) const = 0; }

  9. Virtual functions • Object is an abstract base class. This means that it cannot be directly instantiated. Instead, we will make derived classes that inherit the base class and instantiate them. • Instances of derived class objects will be accessed through the base class interface. • The base class interface therefore needs to be virtual (as opposed to substantial)

  10. Virtual destructor • For example, the base class destructor is virtual. Note that it doesn’t do anything. • The derived class destructor is called through the base class interface. • The same goes for all other virtual functions. The base class version is called first and may be ‘overridden’ by the derived class function of the same name.

  11. Object class virtual methods #include <typeinfo> Object::~Object() {} // Destructor bool Object::IsNull() const { return false; } int Object::Compare(Object const& object) const { if (typeid(*this) == typeid(object)) return CompareTo(object); else if (typeid(*this).before(typeid(object))) return -1; else return 1; } Compare uses CompareTo to compare two objects of the same derived type. It returns negative, 0 or positive values (like strcmp) typeid is a C++ operator returning a reference to an instance of the type_info class (defined in header file <typeinfo>. This class has a member function called name() which returns a pointer to a character string that contains the name of the class. The before() method refers to the inheritance tree.

  12. Pure virtual functions Pure virtual functions contain no implementation (=0). This means they will need to be defined in every concrete class derived from Object. class Object { protected: virtual int CompareTo (Object const&) const = 0; public: virtual ~Object(); virtual bool IsNull() const; virtual int Compare(Object const&) const; virtual void Put(ostream&) const = 0; }

  13. Base class operators • Objects need to be compared. • Now that we have established a mechanism for doing this (Compare and CompareTo) we can use these to build our overloaded operator definitions. • Similarly, we can use Put to built an overloaded << operator

  14. Object class operators inline bool operator==(Object const& left, Object const& right) { return left.Compare(right) == 0; } inline bool operator!=(Object const& left, Object const& right) { return left.Compare(right) != 0; } inline bool operator<=(Object const& left, Object const& right) { return left.Compare(right) <= 0; } inline bool operator<(Object const& left, Object const& right) { return left.Compare(right) < 0; } inline bool operator>=(Object const& left, Object const& right) { return left.Compare(right) >= 0; } inline bool operator>(Object const& left, Object const& right) { return left.Compare(right) > 0; } inline bool operator<<(ostream& s, Object const& object) { object.Put(s); return s; }

  15. Result • This completes a definition for our Object ADT as base class from which other classes may be derived. • Since Object-oriented programming is all about Objects, there must be many derived class possibilities.

  16. Base class hierarchy NullObject Object Wrapper<T> Char Int NullObject is a concrete class. It represents an Object that does not contain anything. Much like an empty set is a type of a set. If we wanted to create objects that did contain things (like a native type item) we could create a ‘Wrapper’ class derived from Object. Then instantiate Char objects, Int objects, Double objects, etc. Double String

  17. Base class hierarchy NullObject Object Wrapper<T> Char Int However, It is usually much easier to use integers, doubles, etc. directly rather than wrapping them in Object classes. Double String These are wrapper classes named for a native type they will ‘wrap up’.

  18. Base class hierarchy NullObject Object Wrapper<T> Char Int Double Container String A more practical ADT that derives from Object is the Container.

  19. Container class inheritance Object Container A Container is an object that holds other objects within it. Since Containers are objects themselves, they are derived from the Object base class. Container is also an abstract base class. Although it derives from Object, we do not intend to instantiate Containers directly. We will create other class definitions that inherit the Container (and hence Object) characteristics first.

  20. Container class definition Class Container : public virtual Object { protected: unsigned int count; // number of items in Container Container(); public: virtual unsigned int Count() const; // accessor for count virtual bool IsEmpty() const; // empty container virtual bool IsFull() const; // full container virtual void Put(ostream&) const; // replaces Object Put virtual Iterator& newIterator() const; virtual void Purge() = 0; // empties a container virtual void Accept(Visitor&) const = 0; }

  21. Container class definition Container::Container() : count(0) {}; // constructor unsigned int Container::Count() const {return count;} bool Container::IsEmpty() const { return Count() == 0; } bool Container::IsFull() const { return false; } The other functions are more complex than we need for now. Put overrides the Object.Put() pure virtual function. A ‘Visitor’ is an Object that interacts with Containers. If the Container accepts the Visitor as valid it will let it visit each Object it contains and run it’s methods on that Object (for example, the Visitor may check to see if the data in an Object matches data it is looking for.

  22. Iterators An Iterator is also an Object. It’s purpose is to provide a method for visiting all of the Objects in a Container, one-by-one. For example: SomeContainer c; Iterator& i = c.NewIterator(); while (!i.IsDone()) { cout << *i << endl; ++i; } delete &i; overloaded operators

  23. Iterator abstract base class Class Iterator { public: virtual ~Iterator(); virtual void Reset() = 0; virtual bool IsDone() const = 0; virtual Object& operator*() const = 0; virtual void operator++() = 0; };

  24. ADT hierarchy Object Container Stack StackAsArray StackAsLinkedList Queue QueueAsArray QueueAsLinkedList Both the Stack ADT and Queue ADT are Containers. They can be written as derived classes of the Container abstract base class we have developed.

  25. Stack abstract base class Class Stack : public virtual Container { public: virtual Object& Top() const = 0; virtual void Push(Object&) = 0; virtual Object& Pop() = 0; };

  26. StackAsArray Class StackAsArray : public Stack { private: Array<Object*> array; class Iter; public: StackAsArray(unsigned int); ~StackAsArray(); void Purge(); void Push(Object& object); Object& Pop(); Object& Top() const; friend class Iter; }; Uses the Array template to create an array of pointers to Objects. The size of the array will be determined by the constructor. This is a nested class definition. Note how it uses the friend designation.

  27. StackAsArray Iter class StackAsArray: : Iter : public Iterator { private: StackAsArray const& stack; unsigned int position; public: Iter(StackAsArray const&); // …other methods it may need to overload, etc. };

  28. StackAsArray methods StackAsArray::StackAsArray(unsigned int size) : array(size) {}; void StackAsArray::Purge() { if (IsOwner()) for (unsigned in i=0; i < count; i++) delete array[i]; count = 0; } StackAsArray::~StackAsArray() { Purge(); } Used by destructor to deallocate array pointers.

  29. StackAsArray methods (con’t) void StackAsArray::Push(Object& object) { assert(count != array.Length()); array[count++] = &object; } Object& StackArray::Pop() { assert(count > 0); return *array[--count]; } Object& StackAsArray::Top() const { assert(count > 0); return *array[count - 1]; // why not count--? }

  30. StackAsArray Iterator StackAsArray::Iter::Iter(StackAsArray conts& _stack) : stack(_stack) { Reset(); } bool StackAsArray::Iter::IsDone() const { return position >= stack.count; } Object& StackArray::Iter::operator*() const // dereferencing operator { if (position < stack.count) return *stack.array[position]; else return NullObject::Instance(); } void StackAsArray::Iter::operator++() { if (position < stack.count) ++ position; } void StackAsArray::Iter::Reset() { position = 0; }

  31. Use of Iterator object StackAsArray stack; stack.Push(*new Int(3)); // int in wrapper Int, an Object stack.Push(*new Int(1)); stack.Push(*new Int(4)); Iterator& i = stack.NewIterator(); while (!i.IsDone()) { cout << *i << endl; // uses overloaded dereference ++i; } delete &i;

  32. StackAsLinkedList Class StackAsLinkedList : public Stack { private: LinkedList<Object*> list; // a linked list of pointers to Objects class Iter; public: StackAsLinkedList(); void Purge(); ~StackAsLinkedList(); void Push(Object& object); Object& Pop(); Object& Top() const; friend class Iter; }

  33. StackAsLinkedList methods StackAsLinkedList::StackAsLinkedList() : list() {}; // constructor void StackAsLinkedList::Purge() { if (IsOwner()) { ListElement<Object*> const* ptr; for (ptr = list.Head(); ptr != 0; ptr=ptr->Next()) delete ptr->Data() } list.Purge(); count = 0; } StackAsLinkedList::~StackAsLinkedList() { Purge(); }

  34. StackAsLinkedList methods void StackAsLinkedList::Push(Object& object) { list.Prepend(&object); ++count; } Object& StackAsLinkedList::Pop() { assert(count > 0); Object& result = *list.First(); list.Extract(&result); --count; return result; } Object& StackAsLinkedList::Top() const { assert(count > 0); return *list.First(); }

  35. StackAsLinkedList methods StackAsLinkedList::Iter::Iter (StackAsLlinkedList const& _stack): stack(_stack) { Reset(); } bool StackAsLinkedList::Iter::IsDone() const { return position == 0; } Object& StackAsLinkedList::Iter::operator*() const { if (position != 0) return *position->Data(); else return NullObject::Instance(); } void StackAsLinkedList::Iter::operator++() { if (position != 0) position = position->Next(); } void StackAsLinkedList::Iter::Reset() { position = stack.list.Head(); }

  36. Use of Iterator object StackAsLinkedList stack; stack.Push(*new Int(3)); stack.Push(*new Int(1)); stack.Push(*new Int(4)); Iterator& i = stack.NewIterator(); while (!i.IsDone()) { cout << *i << endl; ++i; } delete &i;

More Related