Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вопрос? Перегрузка операторов в C# 
:(
    Опции темы
Neuromancer
Дата 29.8.2006, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 23.6.2006

Репутация: нет
Всего: нет



Читаю книгу “Шилдт Полный справочник по С#”

У меня вопрос? Я не хрена не понял, что там Шилдт наколбасил про перегрузки операторов, 
мог бы кто нибуть объяснить поподробней, кое-что, конечно, понял, но не все.

И если можно, то приведите пример с комментариями или ссылку дайте, где можно
прочитать, чтоб там все понятно расписано было и cпримерами.
PM MAIL   Вверх
marcusmae
Дата 29.8.2006, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



Ссылок полно. А вообще, вряд ли сильно много умеющих объяснить лучше Шилдта. smile
То есть, имеет смысл задать более конкретные вопросы о том, что непонятно. Мы попробуем ответить ;)


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
reloni
Дата 29.8.2006, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 10.5.2006
Где: Москва

Репутация: 3
Всего: 4



Цитата(marcusmae @  29.8.2006,  16:04 Найти цитируемый пост)
А вообще, вряд ли сильно много умеющих объяснить лучше Шилдта

Это точноsmile
Но вот пример, практически под копирку списанный у Троелсена, может он поможет:
Код

public class Point
{
    private int _x;
    private int _y;

    public Point(int x, int y)
                {
        this._x = x;
        this._y = y;
    }

    public int X
    {
        get { return this._x; }
    }

    public int Y
    { 
        get { return this._y; } 
    }

    // собственно перегрузка оператора +
    public static Point operator +(Point cl1, Point cl2)
    {
        return Add(cl1, cl2);
    }

    private static Point Add(Point cl1, Point cl2)
    {
        return new Point(cl1.X + cl2.X, cl1.Y + cl2.Y);
    }

    // перегрузка оператора -
                public static Point operator -(Point cl1, Point cl2)
    {
        return Sub(cl1, cl2);
    }

    private static Point Sub(Point cl1, Point cl2)
    {
        return new Point(cl1.X - cl2.X, cl1.Y - cl2.Y);
    }

    // переопределяем метод ToString для простоты вывода на консоль
    public override string ToString()
    {
        return "X= " + this.X.ToString() + ", Y= " + this.Y.ToString();
    }
}


Перегрузки "+" и "-" вызывают соответственно методы Add и Sub, в принципе можно и не плодить дополнительных методов. Эти метды возвращают новый класс, с измененными координатами. Теперь можно написать:

Код

Point cl1 = new Point(1, 5);
Point cl2 = new Point(-8, 10);
Point cl3 = cl1 + cl2;
Console.WriteLine(cl3.ToString());

PM MAIL ICQ   Вверх
marcusmae
Дата 29.8.2006, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


stravaganza
**


Профиль
Группа: Участник
Сообщений: 874
Регистрация: 26.3.2006

Репутация: 22
Всего: 39



smile Тогда, чтобы было совсем понятно, добавлю, что в 

Код

    // переопределяем метод ToString для простоты вывода на консоль
    public override string ToString()
    {
        return "X= " + this.X.ToString() + ", Y= " + this.Y.ToString();
    }


override потому что подразумевается переопределение метода, унаследованного классом Point  от System.Object :

Код

public class Point : System.Object


который определяет методы GetType(), ToString(), Equal(), GetHashCode() и др. :

Код

    // из метаданных
    public class Object
    {
        public Object();

        public virtual bool Equals(object obj);
        public static bool Equals(object objA, object objB);

        public virtual int GetHashCode();
        public Type GetType();

        protected object MemberwiseClone();
        public static bool ReferenceEquals(object objA, object objB);

        public virtual string ToString();
    }


и ещё, функции перегрузки операторов всегда статические (static). То есть, общие для всех экземпляров класса Point.

Это сообщение отредактировал(а) marcusmae - 29.8.2006, 18:54


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
ivashkanet
Дата 30.8.2006, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



reloni, попробую я немного объяснить smile

На примере операции "+".
Этот символ обозначает разные операции.
Например 1+1 --- опирация сложения чисел (ответ 2)
А если "1" -- строка, то + будет складывать именно строки, а не их значения. 
Алгоритм этого действия другой и в ответе уже будет "11" -- склейка этих строк.

Получается, что результат одной и той же операции зависит от того что мы складываем (это естественно).

По умолчанию, язык C# не в курсе как складываются точки (Point).
Поэтому его нужно этому учить:
Код
public static Point operator +(Point cl1, Point cl2)

Внутри ты можешь поставить любую реализацию (даже попарно умножить их).
Мы только что научили C# складывать Точки.
Можно научить умножать Точку на число:
Код
public static Point operator *(int cl1, Point cl2)

Можно эту же операцию применить к скалярному умножению точек:
Код
public static int operator *(Point cl1, Point cl2)

И так далее....
В последних двух примерах мы и сталкиваемся с перегрузкой. 
Т.е. Когда один и тот же оператор (*) имеет разные реализации (но!, что важно для разных аргументов).

Как же компилятор определяет какую реализацию выбрать?
Очень просто:
Если ты перемножаешь число и Точку (именно в этом порядке smile ), то нужно выбирать первую реализацию, если две точки, то вторую.
Код

Point cl1 = new Point(1, 5);
Point cl2 = new Point(-8, 10);
int i = 5;

Point cl3 = i * cl2; // Можно было написать 5 * cl2
// cl3 = cl2 * i  --- выдаст ошибку компиляции, ведь мы не написали (не определили), 
// что делать если первый параметр точка, а второй число  :thumbs-up 

int j = cl1 * cl2;



PM MAIL WWW ICQ   Вверх
Neuromancer
Дата 30.8.2006, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 23.6.2006

Репутация: нет
Всего: нет



ivashkanet- Спасибо тебе огромное вот люди учитесь, как надо объяснять.  smile 
PM MAIL   Вверх
ivashkanet
Дата 30.8.2006, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодю потиху
****


Профиль
Группа: Участник Клуба
Сообщений: 3684
Регистрация: 23.2.2006
Где: Гомель, Беларусь

Репутация: 47
Всего: 149



Neuromancer, не за что  smile
PM MAIL WWW ICQ   Вверх
VisualProgrammerNET
Дата 30.8.2006, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Почётный халявщик
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.10.2005
Где: Зеленоград

Репутация: 4
Всего: 6



Никогда не любил заморачиваться с этими операторами... проще написать один метод типа 
Код

static Point SumPoints(Point p1, Point p2). 

 smile 


--------------------
3 ГОДА НА user posted image 
PM MAIL ICQ   Вверх
reloni
Дата 30.8.2006, 15:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 10.5.2006
Где: Москва

Репутация: 3
Всего: 4



VisualProgrammerNET, ингда бывает проще написать
Код

p3 = p1 + p2;

Чем вызывать каждый раз статический метод. Особенно если это надо делать часто.
PM MAIL ICQ   Вверх
$tatic
Дата 2.9.2006, 13:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 651
Регистрация: 28.1.2005

Репутация: 2
Всего: 22



Для векторов и матриц к тому же полезно. Хотя для векторов и существует два типа умножения.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0591 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.