%------------------------------------------------------------------- // Προβληματική συνάρτηση, αν κληθεί με κάτι άλλο από μεταβλητή, // αφού απαγορεύεται να χρησιμοποιηθεί αναφορά σε προσωρινό αντικείμενο. void print_bad( std::string& s ) { // όρισμα χωρίς const std::cout << s << std::endl; } // Καλώς ορισμένη συνάρτηση: void print_good( const std::string& s ) { std::cout << s << std::endl; } std::string hello("Hello"); print_bad( hello ); // επιτυχής μεταγλώττιση, αφού το hello δεν είναι προσωρινό print_bad( std::string("World") ); // λάθος, το όρισμα είναι προσωρινό print_bad( "!" ); // λάθος, κατασκευάζεται προσωρινό std::string από const char* print_good( hello ); // επιτυχής μεταγλώττιση print_good( std::string("World") ); // επιτυχής μεταγλώττιση print_good( "!" ); // επιτυχής μεταγλώττιση %------------------------------------------------------------------- class MyClass { int x; char c; std::string s; }; MyClass& MyClass::operator=( const MyClass& other ) { x = other.x; // other : το αντικείμενο δεξιά του τελεστή = c = other.c; s = other.s; // this : δείκτης προς το τρέχον αντικείμενο, return *this; // δηλαδή προς το αντικείμενο αριστερά του τελεστή = } %------------------------------------------------------------------- #include #include using namespace std; class Test { public: Test() {} Test(const Test &t) { cout << "Copy constructor called" << endl; } Test& operator = (const Test &t) { cout << "Assignment operator called" << endl; } }; int main() { Test t1, t2; // Δημιουργία των στιγμιοτύπων t1 και t2 t2 = t1; // Στο t2 γίνεται ανάθεση του t1 Test t3 = t1; // Δημιουργία του στιγμιοτύπου t3 με αντιγραφή του t1 σε αυτό // Είναι ισοδύναμο με: Test t3(t1); } // έξοδος στην οθόνη: // Assignment operator called // Copy constructor called %------------------------------------------------------------------- // αρχείο Ratio.h #pragma once class Ratio { public: Ratio(); // κατασκευή Ratio(int); // κατασκευή Ratio(int,int); // κατασκευή ~Ratio(); // καταστροφή int getNumerator() const; // πρόσβαση int getDenominator() const; // πρόσβαση void setNumerator(int); // πρόσβαση void setDenominator(int); // πρόσβαση double toDouble(); // πραγματική τιμή void invert(); // αντιστροφή void print(); // εκτύπωση void add(const Ratio&, Ratio&) const; // υπερφόρτωση τελεστή + Ratio& operator+(const Ratio& rhs); // υπερφόρτωση τελεστή << friend std::ostream& operator<<(std::ostream& stream, const Ratio& rhs); private: int num; // αριθμητής int den; // παρανομαστής }; %------------------------------------------------------------------- #include // αρχείο Ratio.cpp #include "Ratio.h" Ratio::Ratio() { num=0; den=1; } Ratio::Ratio(int i) { num=i; den=1; } Ratio::Ratio(int i,int j) { num=i; den=j; } Ratio::~Ratio() { } int Ratio::getNumerator() const { return num; } int Ratio::getDenominator() const { return den; } void Ratio::setNumerator(int i) { num=i; } void Ratio::setDenominator(int i) { den=i; } double Ratio::toDouble() { return (double) num / (double) den; } void Ratio::invert() { int tmp=num; num=den; den=tmp; } void Ratio::print() { std::cout << num << "/" << den; } void Ratio::add(const Ratio& b, Ratio& c) const { int num2=b.getNumerator(); int den2=b.getDenominator(); int num3=num*den2+num2*den; int den3=den*den2; c.setNumerator(num3); c.setDenominator(den3); } Ratio& Ratio::operator+(const Ratio& rhs) { // int n2=rhs.getNumerator(); // int d2=rhs.getDenominator(); // int n3=num*d2+n2*den; // int d3=den*d2; // num=n3; // den=d3; (*this).add(rhs,*this); // χρήση της μεθόδου add που υλοποιήθηκε return *this; } std::ostream& operator<<(std::ostream& stream, const Ratio& rhs) { stream << rhs.num << "/" << rhs.den; return stream; } %------------------------------------------------------------------- #include // αρχείο Ratio.cpp #include "Ratio.h" Ratio::Ratio() { num=0; den=1; } Ratio::Ratio(int i) { num=i; den=1; } Ratio::Ratio(int i,int j) { num=i; den=j; } Ratio::~Ratio() { } int Ratio::getNumerator() const { return num; } int Ratio::getDenominator() const { return den; } void Ratio::setNumerator(int i) { num=i; } void Ratio::setDenominator(int i) { den=i; } double Ratio::toDouble() { return (double) num / (double) den; } void Ratio::invert() { int tmp=num; num=den; den=tmp; } void Ratio::print() { std::cout << num << "/" << den; } void Ratio::add(const Ratio& b, Ratio& c) const { int num2=b.getNumerator(); int den2=b.getDenominator(); int num3=num*den2+num2*den; int den3=den*den2; c.setNumerator(num3); c.setDenominator(den3); } Ratio& Ratio::operator+(const Ratio& rhs) { // int n2=rhs.getNumerator(); // int d2=rhs.getDenominator(); // int n3=num*d2+n2*den; // int d3=den*d2; // num=n3; // den=d3; (*this).add(rhs,*this); // χρήση της μεθόδου add που υλοποιήθηκε return *this; } std::ostream& operator<<(std::ostream& stream, const Ratio& rhs) { stream << rhs.num << "/" << rhs.den; return stream; } %------------------------------------------------------------------- #include // αρχείο Ratio.cpp #include "Ratio.h" Ratio::Ratio() { num=0; den=1; } Ratio::Ratio(int i) { num=i; den=1; } Ratio::Ratio(int i,int j) { num=i; den=j; } Ratio::~Ratio() { } int Ratio::getNumerator() const { return num; } int Ratio::getDenominator() const { return den; } void Ratio::setNumerator(int i) { num=i; } void Ratio::setDenominator(int i) { den=i; } double Ratio::toDouble() { return (double) num / (double) den; } void Ratio::invert() { int tmp=num; num=den; den=tmp; } void Ratio::print() { std::cout << num << "/" << den; } void Ratio::add(const Ratio& b, Ratio& c) const { int num2=b.getNumerator(); int den2=b.getDenominator(); int num3=num*den2+num2*den; int den3=den*den2; c.setNumerator(num3); c.setDenominator(den3); } Ratio& Ratio::operator+(const Ratio& rhs) { // int n2=rhs.getNumerator(); // int d2=rhs.getDenominator(); // int n3=num*d2+n2*den; // int d3=den*d2; // num=n3; // den=d3; (*this).add(rhs,*this); // χρήση της μεθόδου add που υλοποιήθηκε return *this; } std::ostream& operator<<(std::ostream& stream, const Ratio& rhs) { stream << rhs.num << "/" << rhs.den; return stream; } %------------------------------------------------------------------- // αλλαγή των γραμμών 24--33 του αρχείου Ratio.cpp σε: Ratio operator+(const Ratio& lhs, const Ratio& rhs) { Ratio res; // δημιουργία του αντικειμένου res lhs.add(rhs,res); // lhs + rhs --> αποθήκευση στο res return res; // επιστροφή του res } %------------------------------------------------------------------- #include #include "Ratio.h" using namespace std; int main() { Ratio x(1,2), y(1,2), z(1,2); cout << "x=" << x << " y=" << y << " z=" << z << endl; cout << "x+y+z=" << (x+y+z) << endl; cout << "x=" << x << " y=" << y << " z=" << z << endl; cout << "y+1=" << (y+1) << endl; cout << "x=" << x << " y=" << y << " z=" << z << endl; //--- χρησιμοποιούνται με τη σωστή υλοποίηση του + cout << "1+z=" << (1+z) << endl; // <--- g++ errors... cout << "x=" << x << " y=" << y << " z=" << z << endl; } %------------------------------------------------------------------- Ratio q1(1,2),q2(1,2), q3(1,2); cout << "q1=" << q1 << " q2=" << q2 << " q3=" << q3 << endl; q1+=q2+q3; cout << "q1+=q2+q3 => q1=" << q1 << endl; cout << "q1=" << q1 << " q2=" << q2 << " q3=" << q3 << endl; q1+=10+q2; cout << "q1+=10+q2 => q1=" << q1 << endl; cout << "q1=" << q1 << " q2=" << q2 << " q3=" << q3 << endl; q1+=q3+4; cout << "q1+=q3+4 => q1=" << q1 << endl; cout << "q1=" << q1 << " q2=" << q2 << " q3=" << q3 << endl; %-------------------------------------------------------------------