بخش ۹ - سربارگذاری عملگرها
در این بخش مباحثی پیرامون سربارگذاری عملگرها مطرح میشوند. علاوه بر سربارگذاری عملگرهای ساده مانند + و =+، عملگر درج در جریانهای خروجی نیز سربارگذاری میشود. علاوه بر مباحث مربوط به سربارگذاری عملگرها، توابع عضو ثابت و همچنین توابع دوست نیز مورد اشاره قرار میگیرند. مثالهای این بخش پیادهسازی یک تایپ برای اعداد مختلط هستند.
فهرست مثالها
در این بخش کلاس Complex برای استفاده از اعداد مختلط تعریف میشود. اعمال جمع و افزایش از طریق متدهای عادی قابل اعمال روی اعداد هستند.
#include <iostream> using namespace std; class Complex { public: Complex(double r, double i) : real(r), imag(i) {} Complex(double r) : real(r), imag(0) {} void print() const; Complex add(const Complex& c) const; void inc(const Complex& c); double re() const { return real; } double im() const { return imag; } private: double real; double imag; }; Complex Complex::add(const Complex& c) const { return Complex(real + c.real, imag + c.imag); } void Complex::inc(const Complex& c) { real += c.real; imag += c.imag; } void Complex::print() const { cout << real; if (imag > 0) cout << '+' << imag << 'i'; else if (imag < 0) cout << imag << 'i'; } int main() { Complex a(1, 2); Complex b(4, -2); const Complex zero(0,0); zero.inc(a); // compile error zero.print(); // OK! a.print(); // 1+2i b.print(); // 4-2i Complex c = a.add(b); c.print(); // 5 b.inc(c); // 9-2i b.print(); }
در این بخش، دو عملگر + و =+ برای کلاس اعداد مختلط سربارگذاری میشوند. با داشتن این عملگرها، این کلاس به شکل خواناتر و راحتتری قابل استفاده است.
class Complex { public: // Complex add(const Complex& c) const; Complex operator+(const Complex& c) const; // void inc(const Complex& c); Complex& operator+=(const Complex& c); }; //Complex Complex::add(const Complex& c) const Complex Complex::operator+(const Complex& c) const { return Complex(real + c.real, imag + c.imag); } //void Complex::inc(const Complex& c) Complex& Complex::operator+=(const Complex& c) { real += c.real; imag += c.imag; return *this; } int main() { Complex a(1, 2); Complex b(4, -2); // Complex c = a.add(b); Complex c = a + b; c.print(); // 5 // b.inc(c); b += c; b.print(); // 9-2i b.operator+(c); (b += c).print(); }
در این بخش، عملگر + برای جمع یک عدد مختلط با یک عدد حقیقی سربارگذاری شده است. به این ترتیب، میتوان عباراتی مانند c + 2.5 داشت که در آن c یک عدد مختلط است.
class Complex { public: Complex operator+(double r) const; }; Complex Complex::operator+(double r) const { return Complex(real + r, imag); } int main() { Complex a(1, 2); Complex c = a + 2; c.print(); // 3+2i }
در این بخش، عملگر + برای جمع یک عدد مختلط با یک عدد حقیقی سربارگذاری شده است. به این ترتیب، میتوان عباراتی مانند 2.5 + c داشت که در آن c یک عدد مختلط است.
Complex operator+(const double r, const Complex& c) { return Complex(c.re() + r, c.im()); } int main() { Complex a(1, 2); Complex c = 2 + a; c.print(); // 3+2i }
در این بخش، عملگر >> برای درج یک عدد مختلط در یک جریان خروجی سربارگذاری میشود.
ostream& operator<<(ostream& out, const Complex& c) { out << c.re(); if (c.im() > 0) out << '+' << c.im() << 'i'; else if (c.im() < 0) out << c.im() << 'i'; return out; } int main() { Complex a(1, 2); Complex b(4, -2); cout << a << b << endl; }
در این بخش، عملگر >> به عنوان دوست کلاس Complex تعریف میشود و در نتیجه میتواند به اعضای خصوصی این کلاس دسترسی داشته باشد. طبیعتاً چنین کاری برخلاف اصول برنامهنویسی شیءگرا است و مخفیسازی اطلاعات را زیر سؤال میبرد. به همین دلیل استفاده از این امکان جز در موارد خاص توصیه نمیشود. یکی از این موراد سربارگذاری عملگر >> است.
class Complex { friend ostream& operator<<(ostream& out, const Complex& c); }; ostream& operator<<(ostream& out, const Complex& c) { out << c.real; if (c.imag > 0) out << '+' << c.imag << 'i'; else if (c.imag < 0) out << c.imag << 'i'; return out; }