User Tools

Site Tools


cpp:interfaces

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
cpp:interfaces [2017/04/25 13:04]
gthanos
cpp:interfaces [2019/05/10 07:22]
gthanos
Line 1: Line 1:
 ====== Interfaces ====== ====== Interfaces ======
  
-Η C++ δεν διαθέτει //interfaces// με τον αυστηρά ορισμένο τρόπο που αυτά ορίζονται στη Java. Αντ' αυτού υλοποιεί την λειτουργικότητα των //interfaces// μέσω //[[cpp:polymorphism#pure_virtual_συναρτήσεις_και_abstract_κλάσεις|abstract]]// κλάσεων, δηλαδή κλάσεων που δεν μπορούν να δώσουν αντικείμενα. Στο παράδειγμα που ακολουθεί ορίζουμε το interface+Η C++ δεν διαθέτει //interfaces// με τον αυστηρά ορισμένο τρόπο που αυτά ορίζονται στη Java. Αντ' αυτού υλοποιεί την λειτουργικότητα των //interfaces// μέσω //[[cpp:polymorphism#pure_virtual_συναρτήσεις_και_abstract_κλάσεις|abstract]]// κλάσεων, δηλαδή κλάσεων που δεν μπορούν να δώσουν αντικείμενα. Στο παράδειγμα που ακολουθεί ορίζουμε το interface Stack το οποίο μπορεί να αποθηκεύει ακεραίους. 
 + 
 +Η //abstract base class Stack// έχει δύο υποκλάσεις την κλάση //ArrayStack// που υλοποιεί τη στοίβα μέσω ενός πίνακα και την κλάση //LinkedStack// που υλοποιεί τη στοίβα μέσω απλά συνδεδεμένης λίστας. 
 + 
 +<code cpp Stack.h> 
 +#include <iostream> 
 +using namespace std; 
 + 
 +#ifndef __STACK_H__ 
 +#define __STACK_H__ 
 + 
 +class Stack { 
 +  public: 
 +    virtual int size()=0; 
 +    virtual void push(int o)=0; 
 +    virtual int pop()=0; 
 +    virtual int top()=0; 
 +}; 
 +#endif 
 +</code> 
 + 
 +<code cpp ArrayStack.h> 
 +#include <iostream> 
 +using namespace std; 
 + 
 +#include "Stack.h" 
 + 
 +#ifndef __ARRAYSTACK_H__ 
 +#define __ARRAYSTACK_H__ 
 + 
 +class ArrayStack : public Stack { 
 +  int *array; 
 +  int stackSize, capacity; 
 +  public: 
 +    ArrayStack(int capacity=16); 
 +    int size(); 
 +    void push(int o); 
 +    int pop(); 
 +    int top(); 
 +}; 
 +#endif 
 +</code> 
 + 
 +<code cpp ArrayStack.cpp> 
 +#include "ArrayStack.h" 
 + 
 +ArrayStack::ArrayStack(int cap) { 
 +  capacity = cap; 
 +  stackSize = 0; 
 +  array = new int[capacity]; 
 +
 + 
 +int ArrayStack::size() { 
 +  return stackSize; 
 +
 + 
 +void ArrayStack::push(int o) { 
 +  if(stackSize==capacity) { 
 +    int *_array = new int[2*capacity]; 
 +    for(int i=0; i<stackSize; i++) 
 +      _array[i] = array[i]; 
 +    delete[] array; 
 +    array = _array; 
 +  } 
 +  array[stackSize++] = o; 
 +
 + 
 +int ArrayStack::pop() { 
 +  return array[--stackSize]; 
 +
 + 
 +int ArrayStack::top() { 
 +  return array[stackSize]; 
 +
 +</code> 
 + 
 +<code cpp LinkedStack.h> 
 +#include <iostream> 
 +using namespace std; 
 + 
 +#include "Stack.h" 
 + 
 +#ifndef __LINKEDSTACK_H__ 
 +#define __LINKEDSTACK_H__ 
 + 
 +class LinkedNode { 
 +  int element; 
 +  LinkedNode *next; 
 +public:  
 +  LinkedNode(LinkedNode *nxt, int e);  
 +  LinkedNode(int e);  
 +  int getElement(); 
 +  LinkedNode* getNext(); 
 +  void setElement(int e); 
 +  void setNext(LinkedNode *nxt); 
 +}; 
 + 
 +class LinkedStack : public Stack { 
 +  int stackSize; 
 +  LinkedNode *head; 
 +public: 
 +  LinkedStack(); 
 +  int size(); 
 +  void push(int o); 
 +  int pop(); 
 +  int top(); 
 +}; 
 +#endif 
 +</code> 
 + 
 +<code cpp LinkedStack.cpp> 
 + 
 +#include "LinkedStack.h" 
 + 
 +/* LinkedNode function  
 + * */ 
 + 
 +LinkedNode::LinkedNode(LinkedNode *nxt, int e) { 
 +  next = nxt; 
 +  element = e; 
 +
 + 
 +LinkedNode::LinkedNode(int e) : LinkedNode(NULL,e) { }  
 +int LinkedNode::getElement() { return element; } 
 +LinkedNode* LinkedNode::getNext() { return next; }  
 +void LinkedNode::setElement(int  e) { element = e; } 
 +void LinkedNode::setNext(LinkedNode *nxt) { next = nxt; } 
 + 
 +/* LinkedStack function  
 + * */ 
 + 
 +LinkedStack::LinkedStack() { 
 +  stackSize = 0; 
 +  head = NULL; 
 +
 + 
 +int LinkedStack::size() { return stackSize; } 
 + 
 +void LinkedStack::push(int o) { 
 +  LinkedNode *node = new LinkedNode(head, o); 
 +  head = node; 
 +  stackSize++; 
 +
 + 
 +int LinkedStack::pop() { 
 +  if(size()==0) 
 +    return -1; 
 +  LinkedNode *node = head; 
 +  head = head->getNext(); 
 +  int ptr = node->getElement(); 
 +  delete node; 
 +  stackSize--; 
 +  return ptr; 
 +
 + 
 +int LinkedStack::top() { 
 +  return head->getElement(); 
 +
 +</code> 
 + 
 +<code cpp StackUsage.cpp> 
 +#include "ArrayStack.h" 
 +#include "LinkedStack.h" 
 + 
 +#define ARRAY_SIZE 10 
 + 
 +void invertArray(int array[], int arraySize, Stack &stack) { 
 +  for(int i=0; i<arraySize; i++) 
 +    stack.push(array[i]); 
 +   
 +  for(int i=0; i<arraySize; i++) 
 +    array[i] = stack.pop(); 
 +
 + 
 +int main() { 
 +   
 +  //ArrayStack st; 
 +  LinkedStack st; 
 +  int array[] = { 100, 99, 98, 97, 96, 95, 94, 93, 92, 91 };   
 +   
 +  for(int e:array) 
 +    cout << e << endl; 
 +  cout << endl; 
 +   
 +  invertArray(array, ARRAY_SIZE, st); 
 +   
 +  for(int e:array) 
 +    cout << e << endl; 
 +
 +</code> 
 + 
 +Ένα Makefile που μεταγλωττίζει τον παραπάνω κώδικα είναι το εξής: 
 +<code makefile Makefile> 
 + 
 +StackUsage: ArrayStack.o LinkedStack.o 
 + g++ -Wall -g -std=c++11 StackUsage.cpp ArrayStack.o LinkedStack.o -o StackUsage 
 + 
 +ArrayStack.o: ArrayStack.cpp ArrayStack.h 
 + g++ -Wall -g -std=c++11 ArrayStack.cpp -c 
 + 
 +LinkedStack.o: LinkedStack.cpp LinkedStack.h 
 + g++ -Wall -g -std=c++11 LinkedStack.cpp -c 
 +  
 +clean: 
 + rm *.o StackUsage 
 + 
 +</code> 
 + 
 +Από τον παραπάνω κώδικα παρατηρούμε ότι η κλάση abstract κλάση //Stack// παρέχει μία σειρά από //virtual// μεθόδους οι οποίες υλοποιούνται στις //ArrayStack// και //LinkedStack//. Η μέθοδος //invertArray// χρησιμοποιεί την abstract κλάση //Stack// ως //interface//. Ανάλογα με το είδος του αντικειμένου τύπου //Stack// με το οποίο θα κληθεί ο παραπάνω κώδικας η εσωτερική υλοποίηση της στοίβας θα είναι διαφορετική. Ο κώδικας όμως που χρησιμοποιεί το //interface// της στοίβας παραμένει αμετάβλητος, ανεξάρτητα από την εσωτερική υλοποίηση. 
 + 
 +<WRAP center round tip 80%> 
 +Τα //interfaces// στη C++ υλοποιούνται αποκλειστικά μέσω abstract κλάσεων που περιέχουν //pure virtual// συναρτήσεις. Είναι προφανές ότι μία //abstract// κλάση εκτός από //pure virtual// συναρτήσεις μπορεί να περιέχει και //virtual// συναρτήσεις και κανονικές συναρτήσεις, αλλά και μεταβλητές (πεδία). Η παραπάνω παραδοχή "θολώνει" λίγο την έννοια του //interface// στη C++, καθώς επιτρέπει να υπάρχουν δεδομένα και default υλοποιήσεις σε ένα //interface//. Σε κάθε περίπτωση, εάν μία κλάση περιέχει μόνο //pure virtual// συναρτήσεις μπορείτε να θεωρήσετε ότι αντιπροσωπεύει ένα //interface//
 +</WRAP>
  
cpp/interfaces.txt · Last modified: 2021/05/07 08:42 (external edit)