Re[37]: Override для произвольного метода.
От: Sinclair Россия http://corp.ingrammicro.com/Solutions/Cloud.aspx
Дата: 29.12.08 09:20
Оценка: +1 :)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Учи язык прежде чем что-то заявлять!!

Ага, то есть примера, который реализует операторы из CString, я так и не дождусь. Впрочем, уже к этому моменту ты написал 15 строчек кода, а поиска палиндромов в строке как не было, так и нет.

PD>Да, плохо твое дело, если уж не остается ничего, кроме оскорблений. Впрочем, я тебя понимаю. Такой великий специалист и так глупо прокололся

На мой взгляд, прокололся тот, кто продолжает гнуть пальцы в ответ на предложение привести код наследника от CString, который полностью поддерживает его интерфейс. Впрочем, продолжай — мне нравится твой энтузиазм, с которым ты хоронишь свое реноме
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
http://rsdn.org/File/5743/rsdnaddict.GIF
Re[37]: Override для произвольного метода.
От: LaPerouse  
Дата: 29.12.08 10:54
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>Насчет не void — please


Не в void дело, а в том, что в CString создается экземпляр CString
Попробуй сделай класс B для такого класса A:


#include "stdafx.h"
#include "stdlib.h"
#include "string.h"
#include "malloc.h"

[ccode]
class A {
private :
    char* m_str;
public:

operator int()
{
    return atoi(m_str); // error handling skipped
}
operator char*()
{
    return m_str;
}

A concat(A* a)
{
    char* m_result;
    ...
    A* result = new A(m_result);
    return result;
}

A(char* p = NULL)
{
    m_str = strdup(p);
}
virtual ~A()
{
    free(m_str);
}
};


Тебе придется перегрузить в B concat, что и имелось ввиду.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[29]: Override для произвольного метода.
От: 4058  
Дата: 29.12.08 11:59
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


Ответ выделен.

PD>Никакая уважающая себя фирма, никакой уважающий себя автор учебника не станет приводить примеры, которые противоречат существующим правилам игры.


Противоречий нет. Есть время, и есть опыт. То что считалось нормальным при t0, может быть неприемлемо (или не желательно) при t1.

PD>Тем более что речь все же идет не о специально созданном примере, а об исходниках пусть не самого мощного , но все же штатного текстового редактора, который по идее должен использоваться для реальной работы с .doc файлами теми, кто не купил Office (OO тогда не было


Правильно поставлен смайл, т.к. определение "мощности" плохо сочетается с функциональностью и качеством софта. Причем для большинства word-овых файлов сложнее "Hello World" бывает очень сложно использовать этот инструмент.
Wordpad — это сборная солянка из набора готовых законченных компонент, поэтому дальнейший разговор на эту тему не интересен, т.к. аналогично можно приводить примеры для Calc-а и Notepad-а.

PD>>>А MS , вместо того, чтобы стыдиться такого продукта от начинающих, взяла да и выставила его на всеобщее обозрение в качестве примеров. Для других начинающих, надо полагать


Совершенно верно.

4>>Ну и кому еще нужны такие примеры, кроме как начинающих?


PD>Даже если пример содержит только printf("Hello, World"), его писать и выставлять надо сделанным как следует.


В том и дело, что на таких примерах практически невозможно увидеть положительные/отрицательные стороны того или иного подхода.

4>>M$ надеялась, что сможет пересадить львиную долю formo-кодеров на .NET, не получилось...


PD>Что же ты многоточие поставил ? Надо закончить фразу. Не получилось — а почему ? И библиотека хорошая, и язык C# (взятый сам по себе) — лучше C++, логичнее, а вот не получилось. Почему ? Должны же быть причины ?


Причины:
1. Религия. Это очень долгий и неприятный разговор, которому пожалуй место в СВ.
Managed/Unmanaged, C# vs All и т.п.
2. "А мне и так хорошо". Многим вполне достаточно тех средств которые они используют (ибо "задачи" позволяют), зачем еще что-то изучать?
3. "ListView — плохой, не буду я это использовать". Правда есть, т.к. WinForm-ы прикручивали к .NET в очень сжатые сроки и => через .опу, т.к. основной приоритет значился за другими составляющими (мода на Web).

4>>Пытались, но до добра это дело не довело (см. про formo-кодеров).


PD>А почему в случае Win16 -> Win32 все прошло успешно ?


А почему Dos -> Win прошло успешно?
Потому что Win32 был необходим (как глаток долгожданного воздуха), а вот Java/.Net нет.
Re[38]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 29.12.08 12:00
Оценка:
Здравствуйте, LaPerouse, Вы писали:

LP>Тебе придется перегрузить в B concat, что и имелось ввиду.


Совершенно верно. Только один вопрос — а нужно ли мне это делать ? Так-таки мне нужна эта concat ? . Подумай, зачем мне этот производный класс нужен — и поймешь, что мне в нем может оказаться необходимым очень небольшое количество методов.
With best regards
Pavel Dvorkin
Re[39]: Override для произвольного метода.
От: LaPerouse  
Дата: 29.12.08 12:15
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


LP>>Тебе придется перегрузить в B concat, что и имелось ввиду.


PD>Совершенно верно. Только один вопрос — а нужно ли мне это делать ? Так-таки мне нужна эта concat ? . Подумай, зачем мне этот производный класс нужен — и поймешь, что мне в нем может оказаться необходимым очень небольшое количество методов.


1. Я как раз пытаюсь понять, зачем тебе нужен этот производный класс
2. Если не нужен, тогда зачем тебе наследоваться?
3. Почему он тебе не нужен? Я что, пользуясь твоим классом, при сложении двух полиндромов и ожидая получить полиндром, получу вмесо него CString? Тогда в топку.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[40]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 29.12.08 12:20
Оценка: -2 :))
Здравствуйте, LaPerouse, Вы писали:

LP>1. Я как раз пытаюсь понять, зачем тебе нужен этот производный класс

LP>2. Если не нужен, тогда зачем тебе наследоваться?

Что-то я не пойму, с чего ты решил, что не нужен ?

LP>3. Почему он тебе не нужен? Я что, пользуясь твоим классом, при сложении двух полиндромов и ожидая получить полиндром, получу вмесо него CString?

Тогда в топку.

А с чего это ты решил, что складывая два палиндрома (конкатенируя то есть) ты всегда получишь палиндром ?
With best regards
Pavel Dvorkin
Re[38]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 29.12.08 12:48
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Ага, то есть примера, который реализует операторы из CString, я так и не дождусь.


Ну держи


    class CMyString : public CString
    public:
        CMyString(TCHAR* p) : CString(p) {}
        ~CMyString(){}
        }


Можешь использовать operator[], например. Как ни странно, но он наследуется, несмотря на твои уверения, что все не наследуются. operator== хоть и не наследуется (он реализован не членом, а другом), но вполне работает (а с чего бы ему не работать ? передачу ссылки на производный объект методу, которому нужна ссылка на базовый, никто не отменял, а палиндромность при сравнении строк вроде бы роли не играет И т.д. Нельзя использовать только те, которые возвращают CString, но это само собой разумеется, и никакого отношения к наследованию операторов как таковых не имеет — просто метод унаследованного оператора возвращает базовый класс. Еще раз — дело здесь не в наследовании операторов, а в типе результата метода, это же верно для любого обычного метода (тот же concat, к примеру).

>Впрочем, уже к этому моменту ты написал 15 строчек кода, а поиска палиндромов в строке как не было, так и нет.


Поиска палиндромов в строке ? Можно ссылочку, где я обещал это сделать ? IsPalindrom проверяет, является ли строка палиндромом, а искать в строке все палиндромы — была мне нужда

PD>>Да, плохо твое дело, если уж не остается ничего, кроме оскорблений. Впрочем, я тебя понимаю. Такой великий специалист и так глупо прокололся

S>На мой взгляд, прокололся тот, кто продолжает гнуть пальцы в ответ на предложение привести код наследника от CString, который полностью поддерживает его интерфейс.

Хе-хе, батенька, а с чего это ты решил, что я вообще собираюсь полностью поддерживать его интерфейс ? Ссылочку, пожалуйста, где я обещал полностью. Я это вовсе не собираюсь делать, я намерен только то поддерживать, что мне нужно И скажу более — я не хочу, чтобы поддерживалось то, что мне не нужно, так что я (возможно) это вообще скрою. Тебе объяснить как ?

>Впрочем, продолжай — мне нравится твой энтузиазм, с которым ты хоронишь свое реноме


Какая трогательная забота о моем реноме
With best regards
Pavel Dvorkin
Re[41]: Override для произвольного метода.
От: IB Австрия http://rsdn.ru
Дата: 29.12.08 13:08
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>А с чего это ты решил, что складывая два палиндрома (конкатенируя то есть) ты всегда получишь палиндром ?

Ну, то есть, ты считаешь нормальным, что:
CPalindromString s1;
CPalindromString s2;
...
CPalindromString s3 = s1.Concat(s2) // - Invalid Cast Exception

?
Если так, то вопросов больше нет.
... << RSDN@Home 1.2.0 alpha rev. 673>>
http://www.rsdn.org/File/343/537.gif Мы уже победили, просто это еще не так заметно...
Re[41]: Override для произвольного метода.
От: LaPerouse  
Дата: 29.12.08 13:17
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


LP>>1. Я как раз пытаюсь понять, зачем тебе нужен этот производный класс

LP>>2. Если не нужен, тогда зачем тебе наследоваться?

PD>Что-то я не пойму, с чего ты решил, что не нужен ?


Ты сам это сказал
>>Так-таки мне нужна эта concat

LP>>3. Почему он тебе не нужен? Я что, пользуясь твоим классом, при сложении двух полиндромов и ожидая получить полиндром, получу вмесо него CString?

PD>Тогда в топку.

PD>А с чего это ты решил, что складывая два палиндрома (конкатенируя то есть) ты всегда получишь палиндром ?


Э нет, подмена не пройдет. Мы говорим про объекты-полиндромы класса CPalindrome, у которых есть метод isPalindrome()
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[42]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 29.12.08 13:39
Оценка:
Здравствуйте, LaPerouse, Вы писали:

PD>>Что-то я не пойму, с чего ты решил, что не нужен ?


LP>Ты сам это сказал


Что я сказал ? Что класс, который я предлагаю, не нужен ? Или все же, что concat ?

Цитируем полностью. Выделено мной.

///////////////////////////////////////////////////////////////////////////////////////////////////

LP>Тебе придется перегрузить в B concat, что и имелось ввиду.


PD>Совершенно верно. Только один вопрос — а нужно ли мне это делать ? Так-таки мне нужна эта concat ? Подумай, зачем мне этот производный класс нужен — и поймешь, что мне в нем может оказаться необходимым очень небольшое количество методов.



LP>1. Я как раз пытаюсь понять, зачем тебе нужен этот производный класс

LP>2. Если не нужен, тогда зачем тебе наследоваться?

PD>Что-то я не пойму, с чего ты решил, что не нужен ?


LP>Ты сам это сказал


///////////////////////////////////////////////////////////////////////////////////////////////////


Ну и как все это называется ? Я ему про то, что мне не нужна concat, а оказывается. я заявил, что мне этот класс не нужен.


>>>Так-таки мне нужна эта concat


LP>>>3. Почему он тебе не нужен? Я что, пользуясь твоим классом, при сложении двух полиндромов и ожидая получить полиндром, получу вмесо него CString?

PD>>Тогда в топку.

PD>>А с чего это ты решил, что складывая два палиндрома (конкатенируя то есть) ты всегда получишь палиндром ?


LP>Э нет, подмена не пройдет. Мы говорим про объекты-полиндромы класса CPalindrome, у которых есть метод isPalindrome()


Но отнюдь не метод конкатенации. Его просто не будет. Я не намерен позволять конкатенировать строки какого бы то ни было происхождения. И создавать их в программе тоже. Все, что мне надо — контроль на вводе, и это есть единственный способ их конструирования. См. в MFC DDX-DDV.
With best regards
Pavel Dvorkin
Re[42]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 29.12.08 13:43
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>А с чего это ты решил, что складывая два палиндрома (конкатенируя то есть) ты всегда получишь палиндром ?

IB>Ну, то есть, ты считаешь нормальным, что:
IB>[code]
IB>CPalindromString s1;
IB>CPalindromString s2;
IB>...
IB>CPalindromString s3 = s1.Concat(s2) // — Invalid Cast Exception

Нет. 'Concat' : is not a member of ...
With best regards
Pavel Dvorkin
Re[43]: Override для произвольного метода.
От: LaPerouse  
Дата: 29.12.08 13:47
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>>>Что-то я не пойму, с чего ты решил, что не нужен ?


LP>>Ты сам это сказал


PD>Что я сказал ? Что класс, который я предлагаю, не нужен ? Или все же, что concat ?


PD>Цитируем полностью. Выделено мной.


PD>///////////////////////////////////////////////////////////////////////////////////////////////////


LP>>Тебе придется перегрузить в B concat, что и имелось ввиду.


PD>>Совершенно верно. Только один вопрос — а нужно ли мне это делать ? Так-таки мне нужна эта concat ? Подумай, зачем мне этот производный класс нужен — и поймешь, что мне в нем может оказаться необходимым очень небольшое количество методов.



LP>>1. Я как раз пытаюсь понять, зачем тебе нужен этот производный класс

LP>>2. Если не нужен, тогда зачем тебе наследоваться?

PD>>Что-то я не пойму, с чего ты решил, что не нужен ?


LP>>Ты сам это сказал


PD>///////////////////////////////////////////////////////////////////////////////////////////////////



PD>Ну и как все это называется ? Я ему про то, что мне не нужна concat, а оказывается. я заявил, что мне этот класс не нужен.


Ты неправильно понял мой пункт 2: "Если не нужен, тогда зачем тебе наследоваться?". Имелось ввиду, "если не нужен метод concat, тогда зачем тебе наследоваться?".


>>>>Так-таки мне нужна эта concat


LP>>>>3. Почему он тебе не нужен? Я что, пользуясь твоим классом, при сложении двух полиндромов и ожидая получить полиндром, получу вмесо него CString?

PD>>>Тогда в топку.

PD>>>А с чего это ты решил, что складывая два палиндрома (конкатенируя то есть) ты всегда получишь палиндром ?


LP>>Э нет, подмена не пройдет. Мы говорим про объекты-полиндромы класса CPalindrome, у которых есть метод isPalindrome()


PD>Но отнюдь не метод конкатенации. Его просто не будет. Я не намерен позволять конкатенировать строки какого бы то ни было происхождения. И создавать их в программе тоже. Все, что мне надо — контроль на вводе, и это есть единственный способ их конструирования. См. в MFC DDX-DDV.


То есть ты намерен запрещать пользователю библиотеки вызывать метод concat у твоего CPolindrom?
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[43]: поправка
От: Pavel Dvorkin Россия  
Дата: 29.12.08 13:56
Оценка: :))
PD>Нет. 'Concat' : is not a member of ...

Сорри, не то написал. Да, InvalidCast. Совершенно верно. Нет такого преобразования потому что.
With best regards
Pavel Dvorkin
Re[44]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 29.12.08 14:11
Оценка: :)
Здравствуйте, LaPerouse, Вы писали:

LP>>>1. Я как раз пытаюсь понять, зачем тебе нужен этот производный класс

LP>>>2. Если не нужен, тогда зачем тебе наследоваться?

LP>Ты неправильно понял мой пункт 2: "Если не нужен, тогда зачем тебе наследоваться?". Имелось ввиду, "если не нужен метод concat, тогда зачем тебе наследоваться?".


Я, конечно, могу неправильно понимать, но фраза в пункте 1 говорит именно о классе, а не о методе concat. А в пункте 2 "если не нужен", что ИМХО относится к производному классу, а не к concat, о которой тут и речи нет. Я не телепат, чтобы угадывать.

Если же вопрос относится именно к методу concat, то на вопрос, зачем мне наследоваться, ответ предельно прост — а с чего ты решил, что я наследовать собрался именно ради concat ? concat мне даром не нужен, но из этого вовсе не следует, то мне не нужно наследование. Я вообще о concat речи не вел, ты ее предложил зачем-то, а теперь, выходит, мне не нужно наследование, поскольку мне не нужна эта concat ? Интересная логика.


LP>То есть ты намерен запрещать пользователю библиотеки вызывать метод concat у твоего CPolindrom?


Обсуждаемо. Может, я вообще закрою его , может, просто соглашусь на InvalidCast, поскольку мне эта проверка на палиндром нужна только на входном контроле( не допускать ввода не палиндромов, например). Если, к примеру. я хочу , чтобы в программе все экземпляры CPalindrom были обязательно палиндромами, то на входном контроле эта проверка и будет делаться, а всякие прочие операции просто не нужны, а concat так просто смысла не имеет. От ситуации зависит.
With best regards
Pavel Dvorkin
Re[45]: Override для произвольного метода.
От: LaPerouse  
Дата: 29.12.08 14:28
Оценка: 1 (1) +6
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PD>Если же вопрос относится именно к методу concat, то на вопрос, зачем мне наследоваться, ответ предельно прост — а с чего ты решил, что я наследовать собрался именно ради concat ? concat мне даром не нужен, но из этого вовсе не следует, то мне не нужно наследование. Я вообще о concat речи не вел, ты ее предложил зачем-то, а теперь, выходит, мне не нужно наследование, поскольку мне не нужна эта concat ? Интересная логика.


Полиморфизм от наследования тебе не нужен, и лишние методы от родителя в конракте CPalindrom не нужны, назови же тогда причину зачем тебе нужно наследование?

Итак, получаем:
1. Бенефит от наследования — полиморфизм — тебе не нужен
2. Метод concat, который тебе достался от предка и который тебе не нужен, мешается.

Так на кой черт тогда использовать наследование?

LP>>То есть ты намерен запрещать пользователю библиотеки вызывать метод concat у твоего CPolindrom?


PD>Обсуждаемо. Может, я вообще закрою его , может, просто соглашусь на InvalidCast, поскольку мне эта проверка на палиндром нужна только на входном контроле( не допускать ввода не палиндромов, например). Если, к примеру. я хочу , чтобы в программе все экземпляры CPalindrom были обязательно палиндромами, то на входном контроле эта проверка и будет делаться, а всякие прочие операции просто не нужны, а concat так просто смысла не имеет. От ситуации зависит.


Ты собрался закрыть в наследнике публичный метод предка? Вот тебе еще один гвоздь в твою идею
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Re[39]: Override для произвольного метода.
От: Sinclair Россия http://corp.ingrammicro.com/Solutions/Cloud.aspx
Дата: 30.12.08 05:18
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Хе-хе, батенька, а с чего это ты решил, что я вообще собираюсь полностью поддерживать его интерфейс ?
Ах, не обещал. Прекрасно. То есть теперь ты предлагаешь в качестве решения всех проблем плодить не просто наследников класса, но еще и более убогих наследников? Твою строку даже сконкатенировать корректно с другой такой же нельзя.

Спасибо, у меня на этом всё.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
http://rsdn.org/File/5743/rsdnaddict.GIF
Re[46]: Override для произвольного метода.
От: Pavel Dvorkin Россия  
Дата: 30.12.08 07:13
Оценка: -1 :)
Здравствуйте, LaPerouse, Вы писали:

LP>Полиморфизм от наследования тебе не нужен, и лишние методы от родителя в конракте CPalindrom не нужны, назови же тогда причину зачем тебе нужно наследование?


На тебе ( и Синклеру) пример. Правда, вместо CString я использовал string из STL — CString с консольными приложениями не очень уместен (хотя и возможен), а флейма на тему "почему это так в MFC и так ли это должно быть" я не хочу




#include <string>
#include <iostream>

using namespace std;

void DoSomething(string& str)
{
}

void test()
{
    class pstring : public string
    {
    public :
        pstring(char* p = "") : string(p) {}
        bool IsPalindrom()
        {
            const char* start = c_str(), *end = start + length() - 1;
            for ( ; start < end &&  *start == *end; start++, end--);
            return start >= end;
        }
    };
    
    pstring str;
    cin >> str;
    if(str.IsPalindrom())
     DoSomething(str);
}

int main()
{
    test();
    return 0;
}



LP>Итак, получаем:

LP>1. Бенефит от наследования — полиморфизм — тебе не нужен

Сейчас нет. В дальнейшем может , и понадобится.

LP>2. Метод concat, который тебе достался от предка и который тебе не нужен, мешается.


Абсолютно не нужен здесь. И масса других не нужна.

LP>Так на кой черт тогда использовать наследование?


Посмотри пример.

LP>Ты собрался закрыть в наследнике публичный метод предка? Вот тебе еще один гвоздь в твою идею


А мне его и закрывать не надо. По умолчанию в языке C++ все закрывается (наследование по умолчанию приватно), так что мне здесь, наоборот, открыть их пришлось. А , собственно, что в этом плохого ? Создается специализированная версия класса, естественно, я вполне могу не хотеть, чтобы те методы, которые я считаю некорректным здесь вызывать, вызывались, так что можно и скрыть. Впрочем, ничего не скрыто в примере. Да и неважно это — класс локализован, за пределами test его просто не существует.

Да, конечно, IsPalindrom можно было бы реализовать хелпером (в данном случае даже без дополнительного класса. хватит просто функции). Но сейчас она инкапсулирована в класс и только для его экзмепляров может вызываться, в то время как в случае хелпера ее можно будет вызывать где угодно и для любых string, чего я вовсе не хочу. А не хочу потому, что мне надо ней полная власть нужна. В пределах pstring понятие "палиндром" существует и определяется приведенным алгоритмом, который я вправе изменить, если хочу. Нигде, кроме как в pstring (то есть в test) об этом никто и узнать не сможет. А выпускать эту IsPalindrom во внешний мир я вовсе не желаю.
Есть и еще один момент против хелпера. Ему protected поля и методы класса string недоступны, а мне — вполне доступны. Я этим здесь не воспользовался, а в другом случае мог бы.

Разумеется, это лишь один из возможных вариантов. Могут быть и другие.
With best regards
Pavel Dvorkin
Re[47]: Override для произвольного метода.
От: Sinclair Россия http://corp.ingrammicro.com/Solutions/Cloud.aspx
Дата: 30.12.08 07:56
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:


D>


PD>#include <string>
PD>#include <iostream>

PD>using namespace std;

PD>void DoSomething(string& str)
PD>{
PD>}

PD>void test()
PD>{
PD>    class pstring : public string
PD>    {
PD>    public :
PD>        pstring(char* p = "") : string(p) {}
PD>        bool IsPalindrom()
PD>        {
PD>            const char* start = c_str(), *end = start + length() - 1;
PD>            for ( ; start < end &&  *start == *end; start++, end--);
PD>            return start >= end;
PD>        }
PD>    };
    
PD>    pstring str;
PD>    cin >> str;
PD>    if(str.IsPalindrom())
PD>     DoSomething(str);
PD>}

PD>int main()
PD>{
PD>    test();
PD>    return 0;
PD>}
PD>

А можно пояснить специально для неграмотных — благодаря какой магии работает строчка cin >> str?


PD>Да, конечно, IsPalindrom можно было бы реализовать хелпером (в данном случае даже без дополнительного класса. хватит просто функции). Но сейчас она инкапсулирована в класс и только для его экзмепляров может вызываться, в то время как в случае хелпера ее можно будет вызывать где угодно и для любых string, чего я вовсе не хочу. А не хочу потому, что мне надо ней полная власть нужна.

Я так и думал, что всё упирается в вопрос власти.

PD>В пределах pstring понятие "палиндром" существует и определяется приведенным алгоритмом, который я вправе изменить, если хочу.

Ты в любом случае можешь изменить алгоритм IsPalindrom, где бы он ни находился.

PD>Нигде, кроме как в pstring (то есть в test) об этом никто и узнать не сможет. А выпускать эту IsPalindrom во внешний мир я вовсе не желаю.

Ну да. Совершенно верно — ты сужаешь применимость своей IsPalindrom. Пока что никакой причины это делать нету. Если ты делаешь ее для себя — всё ок, ты влостелин голактеки. Но если ты выпускаешь библиотеку для внешних потребителей, то приходится думеть не о голактеке, а о них.

PD>Есть и еще один момент против хелпера. Ему protected поля и методы класса string недоступны, а мне — вполне доступны. Я этим здесь не воспользовался, а в другом случае мог бы.

Как я и говорил в самом начале — в хелпер нужно выносить всё, что можно сделать через публичный интерфейс. В данном случае (отвлекаясь от вопросов обоснованности такой реализации) ты используешь внутренние подробности устройства своего pstring, поэтому реализация внутри — хоть и зло, но оправданное.

Кстати, аналогичные причины вынудили разработчиков дотнета включить многие методы в класс строки. Поскольку это — самый популярный класс (его инстансов в среднестатистическом приложении больше, чем любых других), то вопросы производительности очень важны. Ну вот и пришлось прогнуться под изменчивый мир.
Впрочем, это не исчерпывает список причин — сами разработчики достаточно скептически относятся ко многим дизайн-решениям FCL, и в частности класса System.String. Некоторые ошибки они признают и даже исправляют в новых версиях фреймворка.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
http://rsdn.org/File/5743/rsdnaddict.GIF
Re[47]: Override для произвольного метода.
От: LaPerouse  
Дата: 30.12.08 08:23
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


LP>>Полиморфизм от наследования тебе не нужен, и лишние методы от родителя в конракте CPalindrom не нужны, назови же тогда причину зачем тебе нужно наследование?


PD>На тебе ( и Синклеру) пример. Правда, вместо CString я использовал string из STL — CString с консольными приложениями не очень уместен (хотя и возможен), а флейма на тему "почему это так в MFC и так ли это должно быть" я не хочу



PD>

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

#include <string>
#include <iostream>

using namespace std;

void DoSomething(string& str)
{
}

void test()
{
    class pstring : public string
    {
    public :
        pstring(char* p = "") : string(p) {}
        bool IsPalindrom()
        {
            const char* start = c_str(), *end = start + length() - 1;
            for ( ; start < end &&  *start == *end; start++, end--);
            return start >= end;
        }
    };
    
    pstring str;
    cin >> str;
    if(str.IsPalindrom())
     DoSomething(str);
    std::string res = str.substr(2, 4);
}

int main()
{
    test();
    return 0;
}


Значит, пользователь получает твой полиндром и, видя, что он поддерживает интерфейс string радостно начинает делать по-привычке substring — хоба, получает кривой каст. Кстати, вот еще одна проблемка: ты не просто должен будешь переопределить методы, где создается string, для удобного пользования твоим классом, нужно еще предоставить новые методы, возвращающие твой pstring. Двойной удар по печени на ровном месте, где достаточно одного статического метода isPloyndrom.

LP>>Итак, получаем:

LP>>1. Бенефит от наследования — полиморфизм — тебе не нужен

PD>Сейчас нет. В дальнейшем может , и понадобится.


LP>>2. Метод concat, который тебе достался от предка и который тебе не нужен, мешается.


PD>Абсолютно не нужен здесь. И масса других не нужна.


Именно. Абсолютно не нужен

LP>>Так на кой черт тогда использовать наследование?


PD>Посмотри пример.


Твой пример не отвечает на этот вопрос. Он почти один в один повторяет предыдущий и ничего не доказывает.

LP>>Ты собрался закрыть в наследнике публичный метод предка? Вот тебе еще один гвоздь в твою идею


PD>А мне его и закрывать не надо. По умолчанию в языке C++ все закрывается (наследование по умолчанию приватно), так что мне здесь, наоборот, открыть их пришлось. А , собственно, что в этом плохого ? Создается специализированная версия класса, естественно, я вполне могу не хотеть, чтобы те методы, которые я считаю некорректным здесь вызывать, вызывались, так что можно и скрыть. Впрочем, ничего не скрыто в примере. Да и неважно это — класс локализован, за пределами test его просто не существует.


Необходимость скрывания методов предка в наследнике говорит об одном — наследование в данном случае нахрен не нужно.

PD>Да, конечно, IsPalindrom можно было бы реализовать хелпером (в данном случае даже без дополнительного класса. хватит просто функции). Но сейчас она инкапсулирована в класс и только для его экзмепляров может вызываться, в то время как в случае хелпера ее можно будет вызывать где угодно и для любых string, чего я вовсе не хочу. А не хочу потому, что мне надо ней полная власть нужна. В пределах pstring понятие "палиндром" существует и определяется приведенным алгоритмом, который я вправе изменить, если хочу. Нигде, кроме как в pstring (то есть в test) об этом никто и узнать не сможет. А выпускать эту IsPalindrom во внешний мир я вовсе не желаю.


Это чушь.

PD>Есть и еще один момент против хелпера. Ему protected поля и методы класса string недоступны, а мне — вполне доступны. Я этим здесь не воспользовался, а в другом случае мог бы.


Это не сила, а слабость. Чтобы понять это, достаточно взять любой учебник по основам ООП и дочитать до второго абзаца, где демонстрируется преимущество сокрытия данных.
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Социализм — это власть трудящихся и централизованная плановая экономика.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.