User Tools

Site Tools


cpp:interfaces

Differences

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

Link to this comparison view

Next revision
Previous revision
cpp:interfaces [2017/04/25 12:27] – created gthanoscpp:interfaces [Unknown date] (current) – external edit (Unknown date) 127.0.0.1
Line 1: Line 1:
 ====== Interfaces ====== ====== Interfaces ======
  
-Η C++ δεν διαθέτει //interfaces// με τον αυστηρά ορισμένο τρόπο που αυτά ορίζονται στη Java. Αντ' αυτού υλοποιεί την λειτουργικότητα των //interfaces// μέσω //abstract// κλάσεων. Μία κλάση χαρακτηρίζεται //abstract// όταν δεν μπορεί να δώσει αντικείμενα. Για να είναι μία κλάση //abstract// θα πρέπει να έχει τουλάχιστον μία //pure virtual// συνάρτηση (είναι το ανάλογο της abstract μεθόδου στη Java)Μία //pure virtual// μέθοδος είναι μία μέθοδος που έχει τον προσδιοριστή //virtual// +Η 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.1493123272.txt.gz · Last modified: 2017/04/25 11:27 (external edit)