C, PHP, VB, .NET

Дневникът на Филип Петров


* Предефиниране на операции

Публикувано на 29 ноември 2008 в раздел С/С++.

В С++ всяка съществуваща унарна или бинарна операция, в която участва поне един обект от даден клас, може да бъде предефинирана от програмиста. Това дава възможност класовете да бъдат интерпретирани, като нови типове данни, които могат да се използват по начин аналогичен на базовите типове. Предефинирането на операции се осъществява чрез операторни функции. Операторната функция е член-функция или приятелска функция на класа, за който тя е дефинирана. Общата форма на една член-функция оператор е следната:

	<тип-резултат> <име-на-клас>::operator<#>(<аргументи>)
	{
		//изпълнявана операция
	}

Типът на връщания резултат най-често е същият като типа на класа, за който е дефиниран операторът. Операторът, който се предефинира, замества # в конструкцията. Когато една операторна член-функция предефинира бинарен оператор, функцията ще приема само един параметър. Този параметър ще получава обекта, който е от дясната страна на оператора. Обектът от лявата страна е този, който генерира обръщението към операторната функция и точно той се предавa неявно на функцията посредством указателя this.

Пример: Следната програма предефинира операторите +, - и = за клас координатна система:

	#include "stdafx.h"
	#include <iostream>
	using namespace std;

	class coord {
	private:
		int x, y;
	public:
		coord(){
			x=0;
			y=0;
		}
		coord(int x, int y){
			this->x=x;
			this->y=y;
		}
		int get_x(){
			return (this->x);
		}
		int get_y(){
			return (this->y);
		}
		void show(){
			cout << "x = " << get_x() << endl;
			cout << "y = " << get_y() << endl;
		}
		// Бинарни оператори + и -
		coord operator+(coord &);
		coord operator-(coord &);
		// Оператор за присвояване
		coord operator=(coord);
		// Унарни оператори
		coord operator++(); // Префиксен
		coord operator++(int); // Постфиксен
		coord operator--(); // Префиксен
		coord operator--(int); // Постфиксен
	};

	coord coord::operator+(coord &obj){
		coord temp;

		temp.x = this->x+obj.x;
		temp.y = this->y+obj.y;

		return temp;
	}

	coord coord::operator-(coord &obj){
		coord temp;

		temp.x = this->x-obj.x;
		temp.y = this->y-obj.y;

		return temp;
	}

	coord coord::operator=(coord obj){
		this->x = obj.x;
		this->y = obj.y;

		return *this;
	}
	coord coord::operator++(){
		this->x++;
		this->y++;
		return *this;
	}

	coord coord::operator++(int i){
		this->x++;
		this->y++;
		return *this;
	}

	coord coord::operator--(){
		this->x--;
		this->y--;
		return *this;
	}

	coord coord::operator--(int i){
		this->x--;
		this->y--;
		return *this;
	}

	int main(){
		coord o1(5,5), o2(2,-2), o3;
		cout << "O1: " << endl;
		o1.show();
		cout << endl;
		cout << "O2: " << endl;
		o2.show();
		cout << endl;

		cout << "o3 = o1 + o2 =>" << endl;
		o3 = o1 + o2;
		o3.show();
		cout << endl;

		cout << "o3 = o1 - o2 =>" << endl;
		o3 = o1 - o2;
		o3.show();
		cout << endl;

		cout << "o3 = o1 =>" << endl;
		o3 = o1;
		o3.show();
		cout << endl;

		o3++;
		cout << "o3++ =>" << endl;
		o3.show();
		cout << endl;

		++o3;
		cout << "++o3 =>" << endl;
		o3.show();
		cout << endl;

		o3--;
		cout << "o3-- =>" << endl;
		o3.show();
		cout << endl;

		--o3;
		cout << "--o3 =>" << endl;
		o3.show();
		cout << endl;
		return 0;
	}

Операторната функция operator=() връща *this, т.е. тя връща обекта, на който се присвоява стойност. Връщайки като резултат *this, предефинираният оператор за присвояване позволява на обектите да бъдат използвани в поредица от присвоявания. Например:

		о3 = о2 = о1;

При предефиниране на операциите + и - използвахме псевдоними да предаване на стойността. В други случаи може да се наложи да ги предавате по стойност (както направихме с оператора =).

При унарните оператори ако оператора се намира пред операнда (напр. ++o3), то се извиква функцията operator#(). Ако оператора е след операнда (напр. o3++), то се извиква функцията operator#(int i). В този случай на "i" винаги ще се предава стойност 0.

Задача: Препишете горният пример, така че функциите бинарните и унарните оператори да са приятелски функции.

 



9 коментара


  1. Нищо по-различно:

    class coord {
    ...
    friend ostream& operator:<<(ostream& output, const coord& p);
    ...
    }

    ostream& operator<<(ostream& output, const coord& p){
    output << "(" << p.get_x() << ", " << p.get_y() <<")";
    return output;
    }

  2. може ли 1 прост въпрос понеже съм изпаднал в голямо неведение: какво се иска ; или означава :
    -
    " предефиниране на операция << за визуализация на окръжност "
    -
    това да не би да значи изместване на окръжността наляво в 2д или 3д кординатна системи, и ако е така колко да бъде това отместване ?

  3. Не, това ще означава да я предефинираш така, че когато се направи "count << k", където k е окръжност, да се отпечата на екрана информацията за тази окръжност.

  4. може би задавам тъп въпрос но може ли да ми обясниш какво означава obj.x;
    (coord coord::operator-(coord &obj){
    coord temp;

    temp.x = this->x-obj.x;
    temp.y = this->y-obj.y;

    return temp;)
    какво означава obj и каква роля играе :/

  5. obj ти е обект от тип coord (координата) и този обект има две полета - x и y.
    obj.x е да вземеш x координатата на точката

  6. а има ли вариант при който предефинирането на << да не е приятелска функция, а член-функция на класа тъй като се опитах да я направя такава, но ми дава грешка.

Добави коментар

Адресът на електронната поща няма да се публикува


*