Вопрос про перегрузку
От: LIS  
Дата: 17.12.04 16:48
Оценка:
Привет всем!

Давно мучался таким вопросом и вот недавно опять приперло:

Уже давно существует перегрузка методов класса по количеству и типу параметров, но почему нельзя делать перегрузку по типу возращаемого значения? Это сложно реализовать или просто не надо никому? Или это может создать проблемы?

Зачем мне это понадобилось? Приведу такой пример:


// Класс возращаемого значения для BaseClass
class BaseRetVal
{
   int Val1 { get {...} set {...}}
}

// Класс возращаемого значения для ChildClass
// Расширяет функциональность BaseRetVal для ChildClass
class ChildRetVal: BaseRetVal
{
   int Val2 { get {...} set {...}}
}

class BaseClass
{
  private BaseRetVal _m_val;

  public virtual BaseRetVal SomeFunc()
  {
    ...
    return _m_val;
  }
}

// Расширяет функциональность BaseClass
class ChildClass: BaseClass
{
  private ChildRetVal _m_val;

  public override ChildRetVal SomeFunc()
  {
    ...
    return _m_val;
  }
}


Хочеться, что бы при вызове ChildClass.SomeFunc возращался тип ChildRetVal.

Возможно, я чего-то недопонимаю и этого можно добиться другими методами — советы принимаются с благодарностью

Спасибо!
Re: Вопрос про перегрузку
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 17.12.04 17:10
Оценка: +1
function A(X: Integer): string; overload;
function A(X: Integer): Integer; overload;
procedure B(X: Integer); overload;
procdure B(X: string); overload;

B(A(0)); // Как это понимать???
Re[2]: Вопрос про перегрузку
От: LIS  
Дата: 17.12.04 17:37
Оценка:
Здравствуйте, Mystic, Вы писали:

M>
M>function A(X: Integer): string; overload;
M>function A(X: Integer): Integer; overload;
M>procedure B(X: Integer); overload;
M>procdure B(X: string); overload;

M>B(A(0)); // Как это понимать???
M>


Я так и думал что такое спросят
В таком случае спросить у программиста что именно он хочет (я имею в виду компилятор)

Немного уточню: возможно ли такая перегрузка для иерархии классов, т.е. :

// Класс возращаемого значения для BaseClass
class BaseRetVal
{
   int Val1 { get {...} set {...}}
}

// Класс возращаемого значения для ChildClass
// Расширяет функциональность BaseRetVal для ChildClass
class ChildRetVal: BaseRetVal
{
   int Val2 { get {...} set {...}}
}

class BaseClass
{
  private BaseRetVal _m_val;

  public virtual BaseRetVal SomeFunc()
  {
    ...
    return _m_val;
  }


  public virtual void Process(BaseRetVal val)
  {
     ...
  }

}

// Расширяет функциональность BaseClass
class ChildClass: BaseClass
{
  private ChildRetVal _m_val;

  public override ChildRetVal SomeFunc()
  {
    ...
    return _m_val;
  }


  public override void Process(ChildRetVal val)
  {
     ...
  }

...

ChildClass tmp = new ChildClass();


tmp.Process(tmp.SomeFunc());

// вместо tmp.Process((ChildRetVal)tmp.SomeFunc());
// а при попытке выполнить tmp.Process(new BaseRetVal) выдавалось бы предупреждение (или ошибка)

}
Re: Вопрос про перегрузку
От: IPv6 Россия http://www.lumarnia.com/
Дата: 17.12.04 17:53
Оценка: +1
Здравствуйте, LIS, Вы писали:

LIS>Возможно, я чего-то недопонимаю и этого можно добиться другими методами — советы принимаются с благодарностью

конечно недопонимаешь. есть приведение типов, которое конфликтует с тем что ты хочешь (в теории а не твоем примере). а для твоего случая нужно выходной параметр передавать последним в вызовах метода (а сам метод возвращает значение из списка стандартных) — соответсвенно сможешь перегрузить все как тебе удобно
это паралельная идеология (которая в коме кстати применяется) — методы возвращают значения из определенного списка, а под реальный результат используется последний параметр метода
Re[2]: Вопрос про перегрузку
От: LIS  
Дата: 17.12.04 18:20
Оценка:
Здравствуйте, IPv6, Вы писали:

IP>Здравствуйте, LIS, Вы писали:


LIS>>Возможно, я чего-то недопонимаю и этого можно добиться другими методами — советы принимаются с благодарностью

IP>конечно недопонимаешь. есть приведение типов, которое конфликтует с тем что ты хочешь (в теории а не твоем примере). а для твоего случая нужно выходной параметр передавать последним в вызовах метода (а сам метод возвращает значение из списка стандартных) — соответсвенно сможешь перегрузить все как тебе удобно
IP>это паралельная идеология (которая в коме кстати применяется) — методы возвращают значения из определенного списка, а под реальный результат используется последний параметр метода

А можно просвятить в чем мой пример конфликтует с теорией приведения типов?
Вот здесь
Автор: LIS
Дата: 17.12.04
я уточнил что именно я имею в виду.
Если я могу передать в функцию, принимающую параметр типа BaseClassPar параметр типа ChildOfBaseClassPar без лишних движений, то почему я также не могу и возвращать параметры? Ведь с ChildOfBaseClassPar можно делать все, что можно делать с BaseClassPar!

Про передачу выходного параметра я тоже думал — это вариант (возможно так и сделаю), но хотелось бы элегантнее
Re: Вопрос про перегрузку
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 17.12.04 18:25
Оценка:
Здравствуйте, LIS, Вы писали:

LIS>Уже давно существует перегрузка методов класса по количеству и типу параметров, но почему нельзя делать перегрузку по типу возращаемого значения? Это сложно реализовать или просто не надо никому? Или это может создать проблемы?


AFAIR доктор Страуструп в соответствующей главе "Бибилии Партии" очень подробно и понятно отвечает на Ваш вопрос.
[ posted via RSDN@Home 1.1.4 beta 3 r241, accompanied by Metallica — Master Of Puppets ]
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Вопрос про перегрузку
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 17.12.04 19:16
Оценка:
Здравствуйте, LIS, Вы писали:

Платформа (.NET) поддерживает перегрузку по возвращаемому значению. Проблема в том что в синтаксисе большинства языков возможны ситуации когда невозможно определить тип значения, которое функция должна вернуть.
... << RSDN@Home 1.1.4 beta 3 rev. 267>>
AVK Blog
Re: Вопрос про перегрузку
От: Павел Кузнецов  
Дата: 17.12.04 20:01
Оценка: 1 (1)
LIS,

> Уже давно существует перегрузка методов класса по количеству и типу параметров, но почему нельзя делать перегрузку по типу возращаемого значения?


Можно. Давно есть в Ada. При желании можно эмулировать в C++ с помощью возвращения прокси-объекта с операциями приведения к соответствующим типам. Как с этим обстоит в C# —
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re: Вопрос про перегрузку
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.12.04 01:59
Оценка: 1 (1)
Здравствуйте, LIS, Вы писали:

LIS>Это сложно реализовать


Да.

LIS> или просто не надо никому?


Лично мне нужно было несколько раз.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Вопрос про перегрузку
От: Павел Кузнецов  
Дата: 18.12.04 04:16
Оценка: +1
VladD2,

> LIS> Это сложно реализовать


> Да.


Влад, это реализуется не сложнее, чем в C++ выбор из перегруженных функций по типу, стоящему в левой части:
int g(int);
double g(double);


Делай раз:
double(*p)(double) = &g;


Или делай два:
int main()
{
   static_cast<double(*)(double)>(&g);
}


Дело не в сложности реализации, а в том, что авторы языков решили, что это не нужно. Насколько они были в этом правы — совершенно отдельный вопрос.
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[3]: Вопрос про перегрузку
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.12.04 08:18
Оценка: +1
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>Влад, это реализуется не сложнее, чем в C++ выбор из перегруженных функций по типу, стоящему в левой части:


Это сложно реализовать в рамках выбранной граматики языка. Конфликты граматики и неопределенности тоже сложности.

Авторы языков не решают нужно или нет. Они понимают, что нужно. Просто сравнивая бенефит с проблемами принимают выбор в пользу меньших проблем.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: Вопрос про перегрузку
От: Кодт Россия  
Дата: 18.12.04 12:11
Оценка: +3
Здравствуйте, Павел Кузнецов, Вы писали:

>> Уже давно существует перегрузка методов класса по количеству и типу параметров, но почему нельзя делать перегрузку по типу возращаемого значения?


ПК>Можно. Давно есть в Ada. При желании можно эмулировать в C++ с помощью возвращения прокси-объекта с операциями приведения к соответствующим типам. Как с этим обстоит в C# —


С++ без всяких проксей
class BaseResult {...};
class DerivedResult : public BaseResult {...};

class BaseFactory
{
public:
  virtual BaseResult* foo() {...}
};
class DerivedFactory : public BaseFactory
{
public:
  virtual DerivedResult* foo() {...}
};

Перекуём баги на фичи!
Re: Вопрос про перегрузку
От: folk Россия  
Дата: 18.12.04 13:02
Оценка: +1
LIS:

> Уже давно существует перегрузка методов класса по количеству и типу параметров, но почему нельзя делать перегрузку по типу возращаемого значения? Это сложно реализовать или просто не надо никому? Или это может создать проблемы?

>
> Зачем мне это понадобилось? Приведу такой пример:

[]

Если я правильно понял, на самом деле тебе хочется не перегрузки по типу возвращаемого значения, а возвращения ковариантного (covariant) типа.
В С++ это реализовано. Фича удобная, в плюсах проблем не создает (кроме переносимости — не поддерживается древними компиляторами).
Posted via RSDN NNTP Server 1.9 delta
На самом деле, люди не читают газеты, они принимают их каждое утро, так же как ванну. ©Маршалл Мак-Льюэн
Re[3]: Вопрос про перегрузку
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.12.04 13:19
Оценка: +1
Здравствуйте, Кодт, Вы писали:

К>С++ без всяких проксей

К>
К>class BaseResult {...};
К>class DerivedResult : public BaseResult {...};

К>class BaseFactory
К>{
К>public:
К>  virtual BaseResult* foo() {...}
К>};
К>class DerivedFactory : public BaseFactory
К>{
К>public:
К>  virtual DerivedResult* foo() {...}
К>};
К>

К>

А какова по-твоему разница между перегрузкой и переопределением?
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Вопрос про перегрузку
От: Кодт Россия  
Дата: 18.12.04 14:00
Оценка: 2 (1)
Здравствуйте, VladD2, Вы писали:

VD>А какова по-твоему разница между перегрузкой и переопределением?


Ну, у меня возникло подозрение, что LIS спросил про переопределение с возвращением ковариантного типа.
Если же именно про перегрузку — то тем более нет проблем (в С++).
Перекуём баги на фичи!
Re[4]: Вопрос про перегрузку
От: Павел Кузнецов  
Дата: 18.12.04 20:02
Оценка:
VladD2,

> ПК> Влад, это реализуется не сложнее, чем в C++ выбор из перегруженных функций по типу, стоящему в левой части:


> Это сложно реализовать в рамках выбранной граматики языка. Конфликты граматики и неопределенности тоже сложности.


Никаких сложностей в рамках выбранной грамматики тоже нет. Вот пример, наглядно это демонстрирующий:
struct C
{
   C( int );
   operator int() const;
   operator double() const;
};

int main()
{
   int i = C(10);
   double d = C(5);
}

С точки зрения грамматики выделенные строки эквивалентны случаю, если бы C были бы перегруженными по результату функциями.

> Авторы языков не решают нужно или нет.


По крайней мере, в случае C++ можно легко открыть "Дизайн и эволюцию", и убедиться, что подавляющее количество подобных решений начинаются как раз с раздумий, насколько та или иная возможность считается нужной.
Posted via RSDN NNTP Server 1.9 delta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[5]: Вопрос про перегрузку
От: Шахтер Интернет  
Дата: 18.12.04 20:36
Оценка: 2 (2)
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>VladD2,


>> ПК> Влад, это реализуется не сложнее, чем в C++ выбор из перегруженных функций по типу, стоящему в левой части:


>> Это сложно реализовать в рамках выбранной граматики языка. Конфликты граматики и неопределенности тоже сложности.


ПК>Никаких сложностей в рамках выбранной грамматики тоже нет. Вот пример, наглядно это демонстрирующий:

ПК>
ПК>struct C
ПК>{
ПК>   C( int );
ПК>   operator int() const;
ПК>   operator double() const;
ПК>};

ПК>int main()
ПК>{
ПК>   int i = C(10);
ПК>   double d = C(5);
ПК>}
ПК>

ПК>С точки зрения грамматики выделенные строки эквивалентны случаю, если бы C были бы перегруженными по результату функциями.

Я бы сказал, разрешение перегрузки выполняется после синтаксического анализа, так что грамматика тут совершенно не при чем. Всё что нужно -- чуть-чуть модифицировать блок, выбирающий среди списка перегруженных функций наиболее подходящую. Тут, правда, возникает одна проблема.

Для случая

int a=...;
double b=...;

int x=fun(a,b);


мы точно знаем желательный тип возвращаемого значения.
А вот как быть с таким примером?

int g(int);
int g(double);

int fun(int a,double b);
double fun(int a,double b);

...

int x=g(fun(a,b));


Или ещё лучше.

template <class T>
int g(T);

int fun(int a,double b);
double fun(int a,double b);

...

int x=g(fun(a,b));


Понятно, что в этих случаях разрешение перегрузки по типу возвращаемого значения невозможно, но тогда какая от неё польза? По-видимому -- минимальная.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[5]: Вопрос про перегрузку
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.12.04 23:07
Оценка: +1
Здравствуйте, Кодт, Вы писали:

К>Если же именно про перегрузку — то тем более нет проблем (в С++).


Речь именно о прегрузке, причем о перегрузке по типу возвращаемого значения. И тут проблемы не у С++, а у дизайнеров языка. Так как с возникающими неоднозначностями приходится бороться.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Вопрос про перегрузку
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.12.04 23:07
Оценка:
Здравствуйте, Павел Кузнецов, Вы писали:

ПК>С точки зрения грамматики выделенные строки эквивалентны случаю, если бы C были бы перегруженными по результату функциями.


Re: Вопрос про перегрузку
Автор: Mystic
Дата: 17.12.04
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Вопрос про перегрузку
От: VladD2 Российская Империя www.nemerle.org
Дата: 18.12.04 23:07
Оценка: 1 (1) +2
Здравствуйте, Шахтер, Вы писали:

Ш>Понятно, что в этих случаях разрешение перегрузки по типу возвращаемого значения невозможно,


+1

Ш> но тогда какая от неё польза? По-видимому -- минимальная.


Чесно говоря хотелось бы поиметь ее в более простых случаях.

Например мне не очень нравятся конструкции вроде:
TypeOfResult result = (TypeOfResult)Query("некоторый запрос");

Было бы здорово если можно было перегрузить Query по возвращаемому значению. Тогда в него можно было встроить понятное объяснение произошедшей ошибки или еще чего. Ну, и синтаксис стал бы проще.
... << RSDN@Home 1.1.4 beta 3 rev. 207>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.