Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не пользуйтесь функциями типа get/set, объясните смысл написанного 
V
    Опции темы
Fazil6
Дата 15.7.2006, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

 smile 

пример чего? 
Цитата

Я тебя понял. Но это в теории так идеально. А на практике довольно таки неудобно (судя из твоего примера там больше путаницы). Тем более всеравно те же самые значения передаются как параметр

странные вы какие-то люди. Вы, наверное, думаете, что я понятия не имею, что такое на практике ? Поверьте, я пишу программы и знаю, что то о чем я говорю, прекрасно без напрягов реализуется на практике. Особенно начинаешь это вспоминать при сопровождении (особенно чужого кода), при работе над проектом  в команде 

Это сообщение отредактировал(а) Fazil6 - 15.7.2006, 20:07
PM MAIL   Вверх
UnrealMan
Дата 15.7.2006, 22:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Fazil6 @  15.7.2006,  14:25 Найти цитируемый пост)
ты считаешь свои решения безупречными

Уж кто бы говорил... :-‎)

Цитата(Fazil6 @  15.7.2006,  14:25 Найти цитируемый пост)
Опять же, имя метода для установки значения Get - это плохой дизайн.
Если уж делать, то

Цитата(Fazil6 @  15.7.2006,  14:25 Найти цитируемый пост)
по крайней мере это уменьшит зависимость наследника от родителя. Замечания по поводу эфективности передачи по ссылке здесь не принимаются.

Вообще-то выбор между эффективностью+удобством и сопровождаемостью решается не в общем виде, а отдельно для каждого конкретного случая. Я допускаю оба способа.

Цитата(Fazil6 @  15.7.2006,  14:25 Найти цитируемый пост)
совсем не для того, чтобы размазывать реализацию по нескольким классам.

Пока применительно к моей задаче ты не предложил ничего лучшего.

Цитата(Fazil6 @  15.7.2006,  14:25 Найти цитируемый пост)
не думаю, что первоочередная задача программиста неиспользование виртуальных функций.

А «не забивать гвозди микроскопом» – это наверняка не первоочередная задача плотника. Тем не менее, разумный плотник скорее всего воспользуется для забивания гвоздей тем инструментом, который для этого предназначен.

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

Цитата(Fazil6 @  13.7.2006,  12:51 Найти цитируемый пост)
writer - это таже самая виртуальная функция по сути. Просто виртуальность ее ты сам обеспечиваешь. Ну пожалуста.

Это как раз ты используешь виртуальность не по назначению, обеспечивая тот же эффект, что и при вызове функций через их явно прописанные в исходниках указатели.

Цитата(Fazil6 @  15.7.2006,  14:25 Найти цитируемый пост)
и посмотри на название ветки - это был не пример использования полиморфизма, а пример неиспользования доступа к данным.

С этой точки зрения дела обстоят не намного лучше :-‎) Что показывает твой пример? Не может ли, скажем, оказаться, что иногда нам придётся формировать данные вывода, которые при выводе каким-то способом вообще не будут использоваться (а нам всё равно надо будет по-честному заполнять всю структуру данных вывода – иначе при каком-нибудь другом виде вывода недополучим какую-то информацию)? 
PM MAIL   Вверх
Fazil6
Дата 16.7.2006, 00:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



UnrealMan, 
Цитата

Вообще-то выбор между эффективностью+удобством и сопровождаемостью решается не в общем виде, а отдельно для каждого конкретного случая. Я допускаю оба способа.

плохой дизайн вынуждает идти на компромис. Эфективность и сопровождаемость не взаимоисключающие.

Цитата

Пока применительно к моей задаче ты не предложил ничего лучшего.

не собирался и не собираюсь. Не собираюсь тебе ничего доказывать.
Цитата

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

я и не пытался ничего явно указывать. Наоборот, я полностью скрыл всю реализацию и там, где непосредственно вызывается функция с передачей ей указателя объекта для вывода совершенно необязательно известно куда будет производиться вывод. А писать цепочки вызовов, чтобы продемонстрировать, что в месте вызова
Код

 mcl.output(f);
 совсем не обязательно знать, что такое f в задачи примера не входило. Это абстрактный пример, показать, что нарушение инкапсуляции для обеспечения универсальности не требуется, а не пример использования наследования или какая-то реальная программа. Я уже удивляюсь, что нет возмущения, что этот огрызок кода не компилируется в исполняемую программу.
Цитата

С этой точки зрения дела обстоят не намного лучше :-‎) Что показывает твой пример? Не может ли, скажем, оказаться, что иногда нам придётся формировать данные вывода, которые при выводе каким-то способом вообще не будут использоваться (а нам всё равно надо будет по-честному заполнять всю структуру данных вывода – иначе при каком-нибудь другом виде вывода недополучим какую-то информацию)? 

причем здесь формирование данных для вывода? Где у меня в примере формирование данных? Что вы прицепились к структуре данных? Чем твой пример в этом плане от моего отличается? Разве я как-то поразному использую в MyClass данные для вывода?
Цитата

Что показывает твой пример?

мой пример показывает, что для обеспечения вывода данных класс MyClass должен знать , что есть класс Write для вывода и знать его интерфейс и все. И таких классов как MyClass может быть сколько угодно, и они могут быть никак между собой не связаны. Write о них ничего не знает, а они друг о друге.  
А если подходить с точки зрения когда класс вывода будет запрашивать данные у класса и выводить их, то каждый класс(либо просто функция, как тебе удобнее) вывода куда попало, должен знать все эти классы и их интерфейсы, да еще и функции должны быть перегруженные, если все эти классы выдающие данные не связаны наследованием. Это смысл моего примера. И мне непонятно какого ражна вы цепляетесь к деталям типа, что такое SomeData, откуда это берется и что это такое. Строка это. 
 
PM MAIL   Вверх
UnrealMan
Дата 16.7.2006, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(UnrealMan @  15.7.2006,  22:45 Найти цитируемый пост)
Пока применительно к моей задаче ты не предложил ничего лучшего.

Цитата(Fazil6 @  16.7.2006,  00:44 Найти цитируемый пост)
не собирался и не собираюсь. Не собираюсь тебе ничего доказывать.

Что, при виде нетривиальных задач сразу в кусты? :-‎) Тогда к чему все эти твои пустые разговоры про «плохой дизайн»?

Цитата(Fazil6 @  16.7.2006,  00:44 Найти цитируемый пост)
я и не пытался ничего явно указывать

А это тогда что?
Цитата
// выводим в файл
mcl.output(f);
// выводим на принтер
mcl.output(p);

Явное указание функции заменили явным указанием объекта, который ассоциирован с нужным классом, который в свою очередь ассоциирован с нужной функцией. Да, необязательно явно указывать требуемый способ вывода именно в месте вызова mcl.output – это можно сделать раньше, и между явно указанными способами можно делать выбор на этапе выполнения программы (см. мой пример с функциями в пространстве имён Output) – и будет тогда твоё

Цитата(Fazil6 @  16.7.2006,  00:44 Найти цитируемый пост)
там, где непосредственно вызывается функция с передачей ей указателя объекта для вывода совершенно необязательно известно куда будет производиться вывод
(на этапе компиляции).
Но речь-то не идёт о том, где мы размещаем явное указание требуемого способа вывода, – факт в том, что явное указание имеет место.

Цитата(Fazil6 @  16.7.2006,  00:44 Найти цитируемый пост)
причем здесь формирование данных для вывода? Где у меня в примере формирование данных?

Ну правильно, зачем же тебе рассматривать задачи, где могут возникнуть затруднения, когда можно продемонстрировать решение какой-то тривиальной задачки – дабы подтвердить какие-то твои тезисы? :-‎)

Цитата(Fazil6 @  16.7.2006,  00:44 Найти цитируемый пост)
Чем твой пример в этом плане от моего отличается?

Мой пример призван:
1) уточнить, чем станет твоё SomeData в случае, когда требуется сформировать данные вывода;
2) показать, что полиморфизм в таком виде тут не нужен.

Цитата(Fazil6 @  16.7.2006,  00:44 Найти цитируемый пост)
И таких классов как MyClass может быть сколько угодно

Насмешил :-‎) В твоём классе вывод юзает только одно поле данных – d (причём без какой-либо обработки со стороны класса MyClass). Как часто приходится сталкиваться с таким случаем в реальной практике?

Цитата(Fazil6 @  16.7.2006,  00:44 Найти цитируемый пост)
и они могут быть никак между собой не связаны. Write о них ничего не знает, а они друг о друге.

На тебе то же самое:

Код
namespace Output
{
    class ToFile
    {
        // ...
    public:
        // ...
        void Write() { /* ... */ }
    };

    class ToScreen
    {
        // ...
    public:
        // ...
        void Write() { /* ... */ }
    };
}

class UserClass
{
    Data data;
    // ...
public:
    Data Get_data() const { return data; }
    // ...
};

namespace UserClass_
{
    namespace Output
    {
        void ToFile(const UserClass &uc)
        {
            ::Output::ToFile otf;
            // ... // формируем данные вывода и записываем их в otf
            otf.Write();
        }

        void ToScreen(const UserClass &uc)
        {
            ::Output::ToScreen ots;
            // ... // формируем данные вывода и записываем их в ots
            ots.Write();
        }
    }
}

void Func()
{
    UserClass uc;
    // ...
    UserClass_::Output::ToFile(uc);
}

Только теперь я смогу для каждого типа вывода сформировать свои данные (необходимые и понятные именно для него), а не отправлять каждый раз полный джентльменский набор на все случаи жизни. 

Это сообщение отредактировал(а) UnrealMan - 16.7.2006, 18:55
PM MAIL   Вверх
Fazil6
Дата 16.7.2006, 20:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

А это тогда что?

пример с потолка.
Цитата

Явное указание функции заменили явным указанием объекта, который ассоциирован с нужным классом, который в свою очередь ассоциирован с нужной функцией. Да, необязательно явно указывать требуемый способ вывода именно в месте вызова mcl.output – это можно сделать раньше, и между явно указанными способами можно делать выбор на этапе выполнения программы (см. мой пример с функциями в пространстве имён Output) – и будет тогда твоё

Цитата

(на этапе компиляции).
Но речь-то не идёт о том, где мы размещаем явное указание требуемого способа вывода, – факт в том, что явное указание имеет место.

если ты не понимаешь смысл того, что я сказал - это твоя проблема.
Цитата

Мой пример призван:
1) уточнить, чем станет твоё SomeData в случае, когда требуется сформировать данные вывода;

какое это имеет значение в данном вопросе?

а это вообще бред какой-то 
Вопрос
Цитата

причем здесь формирование данных для вывода? Где у меня в примере формирование данных? Что вы прицепились к структуре данных? Чем твой пример в этом плане от моего отличается? Разве я как-то поразному использую в MyClass данные для вывода?

ответ
Цитата

2) показать, что полиморфизм в таком виде тут не нужен.


Цитата

Насмешил :-‎) В твоём классе вывод юзает только одно поле данных – d (причём без какой-либо обработки со стороны класса MyClass). Как часто приходится сталкиваться с таким случаем в реальной практике?
можно подумать, что если бы я написал там еще одно поле и перед выводом сложил их, то это как-то изменило смысл.

Цитата

На тебе то же самое:

совсем не тоже самое.
Код

void Func()
{
    UserClass uc;
    // ...
    UserClass_::Output::ToFile(uc);

    UserClass1 uc1;    //  у тебя появился еще один класс
                                 //  и как быть? Опять вывод переписывать

}

Цитата

Только теперь я смогу для каждого типа вывода сформировать свои данные (необходимые и понятные именно для него), а не отправлять каждый раз полный джентльменский набор на все случаи жизни. 

интересно какую ерунду ты писал бы, если бы я вместо SomeData написал int...
  
PM MAIL   Вверх
Meeer
Дата 16.7.2006, 20:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Господа, это лишняя трата времени и нервов. По-моему все равно каждый останется при своем мнении. Прекращайте! smile 
PM MAIL   Вверх
likehood
Дата 16.7.2006, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


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

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



Цитата(Fazil6 @  16.7.2006,  01:44 Найти цитируемый пост)
Это смысл моего примера. И мне непонятно какого ражна вы цепляетесь к деталям типа, что такое SomeData, откуда это берется и что это такое. Строка это.

Сейчас объясню, но для этого придется вернуться к началу беседы:
Цитата(ivashkanet @  8.7.2006,  16:44 Найти цитируемый пост)
Представьте ситуацию: 
Мы спроектировали класс, который что-то обрабатывает, а потом выводит на экран (ShowOnScreen()). 
Мы продали этот класс. Его используют другие люди. Всем нравится, все в восторге.
Через некоторое время понадобился вывод на принтер. Они связваются с нами, мы лезем в код добавляем метод (SendToPrinter()). Через время понадобился вывод еще на что-нибудь...
Это выход? Вместо того чтобы открыть результат вычислений, после чего любой сможет написать свой вывод на что угодно.

Здесь имелось ввиду, что спроектированный класс (для определенности назовем его Renderer) сам производит нужные вычисления, сохраняет их результат в своих закрытых полях, и сам же выводит все это на экран. Почему Rendedrer сам делает весь вывод, хотя логичнее было бы поручитьт его другому классу (Writer'у)? Да потому что нам нельзя использовать геттеры, а как иначе Writer получит доступ к закрытым полям класса Renderer (и эти поля отнюдь не сводятся к одному единственному string'у). Ведь нельзя же нарушать инкапсуляцию!
Остается единственный выход: сделать в базовом классе Renderer абстрактную ф-ю write, которую можно переопределить в классе RenderToScreen, при этом данные в Renderer'е придется сделать защищенными (protected), иначе как получить к ним доступ (здесь мы еще не знаем, что protected - это тоже плохой дизайн, Fazil6 сказал об этом лишь несколько десятков постов спустя).
Отсюда и фраза:
Цитата(ivashkanet @  8.7.2006,  18:30 Найти цитируемый пост)
ОК, согласен. Но тогда все наши классы будут неподъемными монстрами, с КУЧЕЙ "лишнего" кода, который будет только заботиться о взаиможействии с остальным миром.

ведь тогда надо будет в базовом классе позаботиться не только о выводе данных, но и обо всем остальном, что можно с этими данными делать.
Только Fazil6 не увидел здесь никаких проблем:
Цитата(Fazil6 @  8.7.2006,  19:21 Найти цитируемый пост)
да???????    нифигасе!!!!!

и в последовавшем примере продемонстрировал всю силу ОО-полиморфизма.
Пример неплохой, вот только куда там делся класс Renderer? Нет, конечно суть примера была продемонстрировать как можно изменить структуру программы (при этом класс Renderer мог вообще исчезнуть), но ведь поведение программы должно остаться тем же: кто-то вычисляет исходные данные, которые где-то храняться, их кто-то потом выводит на экран. Вот только класс Write (да и его потомки) не содержат никаких данных. Значит они берут эти данные из параметра SomeData (а откуда их иначе брать), который в таком случае вполне может играть роль класса Renderer. Но не тут-то было: на вопрос "что это за SomeData такое" последовал ответ:
Цитата(Fazil6 @  12.7.2006,  13:50 Найти цитируемый пост)
никакого значения это не имеет. Это пример и это может быть все, что угодно. Не в этом смысл примера.

Ну все, приехали! Как это не имеет значения! Если цель была продемонстрировать всю силу виртуальных функций, то может и не имеет, а если как избавиться от get/set, то это принципиальный момент. Похоже, Fazil6 пошел по первому пути, отсюда и все дальнейшие непонятки. Людям то охото узнать как Writer берет чужие данные без геттеров, не нарушая при этом инкапсуляцию, а Fazil6 пытается при этом доказать что-то другое. Может то что он говорит и правильно (так оно и есть), но только разговор этот немного "не по теме". Такое впечатление, что методу write все равно откуда приходят данные, а SomeData это просто сокет, из которого идет поток байтов. smile 
Короче говоря, из этого примера я так и не понял как можно обойтись без геттеров в данном случае, но судя по тому, что
Цитата(Fazil6 @  15.7.2006,  20:32 Найти цитируемый пост)
Поверьте, я пишу программы и знаю, что то о чем я говорю, прекрасно без напрягов реализуется на практике.

это все же можно сделать и было бы неплохо это увидеть. 
PM MAIL   Вверх
Fazil6
Дата 16.7.2006, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

Людям то охото узнать как Writer берет чужие данные без геттеров, не нарушая при этом инкапсуляцию, а Fazil6 пытается при этом доказать что-то другое.
Writeк ни у кого ничего не берет. Ему данные другие классы сами дают. Если для вас в общем виде не понятно, то конкретизирую.
Например Write в ф-ции write принимает массив строк. Его потомки умеют записать этот массив строк в файл или принтер или на экран или еще куда. Вот класс имеющий данные передает этот массив в функцию write. 
Параметр, передаваемый в write - это не класс, это данные.  
PM MAIL   Вверх
likehood
Дата 16.7.2006, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


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

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



Fazil6, вы хотите сказать, что класс MyClass вместо того, чтобы открывать доступ к своим данным сам выбирает, кому он будет передавать эти данные и в каком виде? На счет того, что ф-ии write передаются данные, а не класс, то здесь наверное имеется ввиду, что это может быть и структура если данные довольно сложные, но в данном случае использование структуры с открытыми полями не будет нарушением инкапсуляции (можно было сделать ф-ю с 10-ю параметрами, но структура удобнее)? Класс MyClass отвечает за обработку и хранение данных, а если понадобиться сделать с данными что-то еще кроме вывода, можно просто добавить в MyClass еще один метод (не обязательно виртуальный) и в данном случае это не преведет к большим изменениям в программе? Я правильно понял мысль? 
PM MAIL   Вверх
skyboy
Дата 16.7.2006, 23:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


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

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



Цитата(baronp @  16.7.2006,  21:36 Найти цитируемый пост)
 Почему Rendedrer сам делает весь вывод, хотя логичнее было бы поручитьт его другому классу (Writer'у)? Да потому что нам нельзя использовать геттеры, а как иначе Writer получит доступ к закрытым полям класса Renderer (и эти поля отнюдь не сводятся к одному единственному string'у). Ведь нельзя же нарушать инкапсуляцию!

вот именно! только место "нельзя" я бы поставил "нежелательно". Категоричность - плохой друг и подлый враг. А касательно данных... Данные формируются в классе Render. Так? Если выводятся им же(или его потомками), то инкапсуляция ненарушена: логика и формирования изображения(первоначальная функциональность) и вывода его на принтер(добавленный метод) в пределах одного класса. Изменим один метод(его логику, структуру опериуемых данных) изменим и другой. А если будем использовать другой класс для вывода, как нам дать понять, что данные имеют другую структуру/формируются по-другому? Getter будет вместо данных возвращать надпись "проверьте свой класс"? Или писать два разных метода рендеринга(под старую логику и новую) и два новых getter'a с разными именами(под данные старой структуры и новой)? Какой вариант предпочтительнее? Когда класс и его потомки вполне самодостаточны или когда один класс "почти универсален", но универсальность эта - липовая и достигается экстенсивными методами? 
PM MAIL   Вверх
Fazil6
Дата 17.7.2006, 01:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата

класс MyClass вместо того, чтобы открывать доступ к своим данным сам выбирает, кому он будет передавать эти данные и в каком виде?
вообще-то "куда" он не выбирает. Куда сказали - туда и передает.
Цитата

Я правильно понял мысль?
вобщем да.  

Это сообщение отредактировал(а) Fazil6 - 17.7.2006, 01:32
PM MAIL   Вверх
likehood
Дата 17.7.2006, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


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

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



Цитата(Fazil6 @  17.7.2006,  02:31 Найти цитируемый пост)
вообще-то "куда" он не выбирает.

"куда" - имеется ввиду методу с определенным прототипом.
Все же если мы пишем класс "на все случаи жизни", то придется предусмотреть множество (в смысле много) операций над данными в самом базовом классе (или если хотите набор прототипов виртуальных ф-ий), что приведет к разрастанию интерфейса класса. Если этот класс библиотечный, предусмотреть все операции над данными будет очень сложно, потому то в GUI классах сложно обойтись без геттеров/сеттеров.


Цитата(skyboy @  17.7.2006,  00:45 Найти цитируемый пост)
 только место "нельзя" я бы поставил "нежелательно".

это было сказано с долей сарказма, категоричность мне вообще не свойственна. 
PM MAIL   Вверх
UnrealMan
Дата 17.7.2006, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Fazil6 @  16.7.2006,  20:22 Найти цитируемый пост)
пример с потолка.

Цитата(Fazil6 @  16.7.2006,  20:22 Найти цитируемый пост)
если ты не понимаешь смысл того, что я сказал - это твоя проблема

Отмазки в рассмотрение не принимаются.

Цитата(UnrealMan @  16.7.2006,  18:45 Найти цитируемый пост)
Мой пример призван:
1) уточнить, чем станет твоё SomeData в случае, когда требуется сформировать данные вывода;

Цитата(Fazil6 @  16.7.2006,  20:22 Найти цитируемый пост)
какое это имеет значение в данном вопросе?

Объясняю на пальцах. Пусть у нас есть классы Class1 и Class2, данные которых нужно выводить. При выводе на экран данных Class1 и Class2 не требуется никаких действий со стороны пользователя, однако при выводе данных Class1 в файл пользователю предлагается в диалоговом окне выбрать путь и имя файла для записи. В свою очередь для вывода в файл данных Class2 от пользователя никаких действий не требуется – объект класса сам предоставляет нужный путь и имя файла. Ну и что ты будешь делать со своим SomeData? А если нам ещё третий класс предстоит разработать – тоже со своими условиями, – что будет тогда? Не такая уж красивая картина получается, правда?

Цитата(Fazil6 @  16.7.2006,  20:22 Найти цитируемый пост)
а это вообще бред какой-то

Это не бред, а напоминание – на всякий случай (только не говори, что у тебя, кроме твоего кода, про ООП больше нигде ничего не упоминалось).

Цитата(Fazil6 @  16.7.2006,  20:22 Найти цитируемый пост)
// у тебя появился еще один класс
// и как быть? Опять вывод переписывать

Ту часть, которая передаёт нужную информацию в объекты классов из ::Output, – да; классы для вывода в ::Output – нет. Только давай уточним насчёт «переписывать»: если у нас идёт обработка данных перед выводом, то нам всё равно придётся где-то её размещать – внутри класса или вне (например, внутри пространства имён UserClass1_::Output). Вообще же класс лучше было бы назвать LibraryClass (LibraryClass1) – дабы подчеркнуть, что каких-либо изменений в него мы уже внести не сумеем – придётся или довольствоваться тем, что есть, или же переписывать весь класс заново (и, возможно, менять все старые объявления объектов).

Цитата(Fazil6 @  16.7.2006,  20:22 Найти цитируемый пост)
если бы я вместо SomeData написал int...

Были бы те же самые проблемы + необходимость для каждого типа писать свой метод write (в классе Write и его наследниках) – кстати, только тогда полиморфизм и будет уместен.

Цитата(baronp @  16.7.2006,  21:36 Найти цитируемый пост)
Остается единственный выход: сделать в базовом классе Renderer абстрактную ф-ю write, которую можно переопределить в классе RenderToScreen, при этом данные в Renderer'е придется сделать защищенными (protected), иначе как получить к ним доступ

Что-то я не понял, как это даст получить доступ к этим данным. Приведи пример.

Цитата(Fazil6 @  15.7.2006,  14:25 Найти цитируемый пост)
Ладно. Примем твою идею с общностью и необходимостью доступа к этим данным из наследников. Используем защищенный интерфейс. Хорошо. Избранный вариант самый гибкий, самый красивый, самый короткий и самый опасный. Это немногим лучше чем открытые данные. Этот интерфейс будет использоваться именно как доступ к переменным (ты так и пользуешься). Весь код использующий этот интерфейс становится зависимым от его реализации. 

Зависимость от реализации тут ни при чём. За классом изначально могут быть закреплены нужные (по условию задачи, которую решает данный класс) неизменные свойства, которые вполне логично задавать в виде полей. Можно было бы считать такой класс структурой данных в стиле C, но тогда определение структуры данных в стиле C пришлось бы сильно притягивать за уши, ибо внутреннее устройство этого класса может быть столь же сложным, как и в любом другом классе, где все члены-данные не являются некими хранилищами свойств, диктуемых в отношении класса условием задачи. 

Это сообщение отредактировал(а) UnrealMan - 17.7.2006, 12:46
PM MAIL   Вверх
Meeer
Дата 18.7.2006, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Я всю тему прочитал с начала, и для меня, как наблюдателя (с большей стороны), более убедительная позиция выглядит со стороны "использования get-ов", т.к. получается код гибче. И это неплохая довольно-таки  привычка(на мой взгляд). Правила существуют что бы их нарушать (всем известно). Можно конечно его и придерживаться (правила). Это решать каждому. smile 
PM MAIL   Вверх
UnrealMan
Дата 18.7.2006, 14:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Meeer @  18.7.2006,  00:11 Найти цитируемый пост)
более убедительная позиция выглядит со стороны "использования get-ов", т.к. получается код гибче

Только в отношении свойств, закреплённых за классом условием задачи. Например, возьмём тот же класс строк STL basic_string и посмотрим на одну из реализаций length():

Код
size_type length() const
    {return (_Len); }

По сути length – тот же get (можно было бы назвать этот метод «Get_Len»), получающий жёстко закреплённое за строкой свойство – длину. Никакого нарушения инкапсуляции тут нет.

В остальных же случаях использования get/set следует избегать. 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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