User Tools

Site Tools


cpp:vector_overloading_unary_operators

Υπερφόρτωση μοναδιαίων τελεστών (unary operators)

Ο παρακάτω πίνακας περιγράφει την υπερφόρτωση των τελεστών στο παράδειγμα της κλάσης Vector που ακολουθεί.

Τελεστής Θέση (πριν ή μετά το αντικείμενο) Περιγραφή Μεταβάλει το αντικείμενο* Φιλική συνάρτηση
+ Πριν Επιστρέφει το άθροισμα των στοιχείων του αντικειμένου. Όχι Όχι
- Πριν Επιστρέφει ένα νέο αντικείμενο τα στοιχεία του οποίου έχουν αντεστραμμένο πρόσημο σε σχέση με το αντικείμενο που εφαρμόζεται. Όχι Όχι
++ Πριν Επιστρέφει μία αναφορά στο τρέχον αντικείμενο, τα στοιχεία του οποίου έχουν αυξηθεί κατά ένα. Ναι Όχι
-- Πριν Επιστρέφει μία αναφορά στο αντικείμενο που περνιέται ως 1η παράμετρος στη φιλική συνάρτηση (δηλαδή το τρέχον αντικείμενο), τα στοιχεία του οποίου έχουν μειωθεί κατά ένα. Ναι Ναι
++ Μετά Επιστρέφει ένα νέο αντικείμενο, που είναι αντίγραφο του αντικειμένου στο οποίο εφαρμόζεται ο τελεστής, πριν την πράξη της αύξησης. Το αντικείμενο στο οποίο εφαρμόζεται ο τελεστής αυξάνει τις τιμές των στοιχείων του κατά 1. Ναι Όχι
-- Μετά Επιστρέφει ένα νέο αντικείμενο, που είναι αντίγραφο του αντικειμένου στο οποίο εφαρμόζεται ο τελεστής, πριν την πράξη της μείωσης. Το αντικείμενο στο οποίο εφαρμόζεται ο τελεστής μειώνει τις τιμές των στοιχείων του κατά 1. Ναι Ναι
* Πριν Επιστρέφει έναν ακέραιο που αποτελεί το γινόμενο των στοιχείων του πίνακα. Όχι Όχι
! Πριν Επιστρέφει ένα νέο αντικείμενο τα στοιχεία του οποίου έχουν αντίστροφη σειρά σε σχέση με το αντικείμενο που εφαρμόζεται. Όχι Ναι
~ Πριν Επιστρέφει ένα νέο αντικείμενο τα στοιχεία του οποίου αποτελούν το binary NOT των στοιχείων του αντικειμένου στο οποίο εφαρμόζεται. Όχι Όχι

* στο οποίο εφαρμόζεται.

Προκειμένου να μπορέσουμε να παρακολουθήσουμε την υπερφόρτωση των τελεστών υπερφορτώνουμε τον τελεστή =. Η επεξήγηση της υπερφόρτωσης του τελεστή = θα δοθεί στη συνέχεια.

Προσέξτε τη διαφορετική δήλωση της συνάρτησης υπερφόρτωσης ανάμεσα στους μοναδιαίους τελεστές αύξησης και μείωσης κατά ένα (++, --) όταν αυτοί εφαρμόζονται πριν και μετά το αντικείμενο (prefix και postfix operators)

Το prototype της συνάρτησης υπερφόρτωσης στην περίπτωση του prefix και postfix increment/decrement τελεστή έχει ως εξής. Στην περίπτωση δήλωσης του τελεστή πριν το αντικείμενο η δήλωση είναι

Vector operator++();
Vector operator--();

Στην περίπτωση δήλωσης του τελεστή μετά το αντικείμενο η δήλωση είναι

Vector operator++(int a);
Vector operator--(int a);

Επίσης, παρατηρήστε ότι οι συναρτήσεις που δεν μεταβάλλουν το αντικείμενο στο οποίο εφαρμόζονται δηλώνονται ως const. Για παράδειγμα, η συνάρτηση

Vector operator~() const;

επιστρέφει ένα νέο αντικείμενο του οποίου τα στοιχεία είναι το binary NOT του αρχικού. Ο αρχικός πίνακας παραμένει αμετάβλητος.

Vector.hpp
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
 
#ifndef _VECTOR_HPP_
#define _VECTOR_HPP_
 
class Vector {
  int *array;
  int size;
 
public:
  Vector(unsigned int length=0);
  Vector(const Vector &v);
  Vector(const Vector *v);
  ~Vector();
  unsigned int length() const;     // return Vector's length.
  int& valueAt(unsigned int pos);  // return a reference to element at position pos
 
  int find(int a) const;           // check if 'a' exists in Vector. Return the position
                                   // If found, return the position of the element.
                                   // Otherwise, return -1
 
  void print() const;              // print to standard output vector values
  void print(string &msg) const;   // print to standard output msg and vector values 
  Vector& operator=(const Vector &v);
 
  int operator+() const;           // returns the sum of Vector elements
  friend int operator*(const Vector&) ;  // returns the product of Vector elements
 
  Vector operator-() const;        // returns a new Vector, containing the negative
                                   // values of the original vector.
  Vector& operator++();            // prefix increment. Returns reference to the existing vector.
  friend Vector& operator--(Vector&);    // prefix decrement. Returns reference to the existing vector.
  Vector operator++(int );         // postfix increment. Returns a new Vector.
  friend Vector operator--(Vector&, int);  // postfix decrement. Returns a new Vector.
 
  Vector operator~() const;        // returns the binary NOT for each element in a new Vector
  friend Vector operator!(const Vector &v);  // returns a copy of the Vector with 
                                             // elements in inverted sequence.
};
 
#endif
Vector.cpp
#include "Vector.hpp"
 
Vector::Vector(unsigned int length) {
  size = length;
  array = new (nothrow) int[size];
  if(array==NULL) {
    cerr << "Memory allocation failure!" << endl;
    exit(-1);
  }
  for(int i=0; i<size; i++)
    array[i] = 0;
}
 
Vector::Vector(const Vector &v) {
  size = v.length();
  array = new (nothrow) int[size];
  if(array==NULL) {
    cerr << "Memory allocation failure!" << endl;
    exit(-1);
  }
  for(int i=0; i<size; i++)
    array[i] = v.array[i];
}
 
Vector::Vector(const Vector *v) {
  size = v->length();
  array = new (nothrow) int[size];
  if(array==NULL) {
    cerr << "Memory allocation failure!" << endl;
    exit(-1);
  }
  for(int i=0; i<size; i++)
    array[i] = v->array[i];
}
 
Vector::~Vector() {
  delete [] array;
}
 
unsigned int Vector::length() const { 
  return size; 
}
 
int& Vector::valueAt(unsigned int pos) {
  if(pos>=length()) {
     cerr << "Invalid position!\n";
     return array[size-1];
  }
  return array[pos];
}
 
int Vector::find(int a) const {
  for(int i=0; i<size; i++) {
    if(array[i] == a)
      return i;
  }
  return -1;
}
 
void Vector::print() const {
  for(int i=0; i<size; i++) {
    cout << array[i];
    if(i==size-1)
      cout << endl;
    else
      cout << ", ";
  }
}
 
void Vector::print(string &msg) const {
  cout << msg;
  print();
}
 
Vector &Vector::operator=(const Vector &v) {
  if(array!=NULL)
    delete [] array;
  size = v.length();
  array = new (nothrow) int[size];
  if(array==NULL) {
    cerr << "Memory allocation failure!" << endl;
    exit(-1);
  }
  for(int i=0; i<size; i++)
    array[i] = v.array[i];
  return *this;
}
 
int Vector::operator+() const{
  int sum=0.0;
  for(int i=0; i<size; i++) {
    sum += array[i];
  }
  return sum;
}
 
Vector Vector::operator-() const{
  Vector v(size);
  for(int i=0; i<size; i++) {
    v.valueAt(i) = -array[i];
  }
  return v;
}
 
//prefix increment
Vector& Vector::operator++() {
  for(int i=0; i<size; i++) {
    array[i]++;
  }
  return *this;
}
 
//prefix decrement
Vector& operator--(Vector& v) {  
  for(int i=0; i<v.size; i++) {
    v.array[i]--;
  }
  return v;
}
 
int operator*(const Vector& v){
  int product = 1;
  for(int i=0; i<v.size; i++)
    product *= v.array[i];
  return product;
}
 
Vector Vector::operator~() const{
  Vector v(size);
  for(int i=0; i<size; i++)
    v.valueAt(i) = ~array[i];
  return v;
}
 
Vector operator!(const Vector &v) {
  Vector n = v;
  for(int i=0; i<v.size; i++)
    n.array[i] = v.array[v.size-1-i];
  return n;
}
 
//postfix increment
Vector Vector::operator++(int a) {
  Vector v(this);
  for(int i=0; i<size; i++) {
    array[i]++;
  }  
  return v;
}
 
//postfix decrement
Vector operator--(Vector& v, int a) {
  Vector w(v);
  for(int i=0; i<v.size; i++) {
    v.array[i]--;
  }  
  return w;
}
VectorUsage.cpp
#include "Vector.hpp"
 
int main() {
  Vector v(5);
  v.valueAt(0) = 2;  v.valueAt(1) = 3;
  v.valueAt(2) = 4;  v.valueAt(3) = 5;  v.valueAt(4) = 6;
 
  string msg = "Initial Vector: ";
 
  v.print(msg);  
  cout << "+v: " << +v << endl;
 
  Vector f = -v;
  f.print(msg="f = -v: "); cout << endl;
 
  cout << "*v: " << *v << endl;
 
  f = !v;
  f.print(msg = "f = !v:  "); cout << endl;
 
  cout << "~2: "<< ~2 << " | ~3: "<< ~3 << " | ~4: "<< ~4 << endl;
  f = ~v;
  f.print(msg = "f = ~v:  "); cout << endl;
 
  f = ++v;  
  f.print(msg = "f = ++v: ");  
  v.print(msg = "v:       ");
  f = --v;  
  f.print(msg = "f = --v: ");  
  v.print(msg = "v:       ");
  cout << endl;
 
  f = v++;
  f.print(msg = "f = v++: ");
  v.print(msg = "v:       ");
  f = v--;
  f.print(msg = "f = v--: ");
  v.print(msg = "v:       ");
}
cpp/vector_overloading_unary_operators.txt · Last modified: 2021/05/24 06:38 (external edit)