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
cpp:interfaces [2021/05/07 08:42]
cpp:interfaces [2021/05/07 09:42]
gthanos
Line 1: Line 1:
 +====== Interfaces ======
 +
 +Η 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)