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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Переменные-члены класса как проблема ООП 
:(
    Опции темы
iipetrov
Дата 21.5.2013, 09:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Согласно парадигме ООП в классе содержатся данные и методы, работающие с этими данными. 
Это создает существенную проблему: нестатический метод совершенно не обязан давать одинаковые результаты на одинаковых входных данных.

Программист, использующий класс, не может положиться на результат работы нестатического метода. Достаточно один раз вызвать неконстантный метод чтобы программа начала давать непредсказуемые результаты.

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

Какие еще есть решения у этой проблемы? Есть ли какие-то общепринятые подходы? 

В качестве примера можно привести такие классы

Код

class Simple
{
  private int a = 0;

  public void add(int b)
  {
    a = a + b;
  }

  public int getA()
  {
    return a;
  }
}

class Difficult
{
  private int a = 0;

  public void add(int b)
  {
    if ((float)(a % 100) / 3 == (int)((a % 100) / 3) )
      a = a + b;
    else
      a = a - b;
  }

  public int getA()
  {
    return a;
  }
}


Если первый класс относительно предсказуем, то про второй класс это уже не сказать.
На практике обычно переменных-членов намного больше, и поведение намного более непредсказуемо.

Это сообщение отредактировал(а) iipetrov - 21.5.2013, 10:56
PM MAIL   Вверх
bsa
Дата 21.5.2013, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(iipetrov @  21.5.2013,  10:39 Найти цитируемый пост)
Это создает существенную проблему: нестатический метод совершенно не обязан давать одинаковые результаты на одинаковых входных данных.
Жизнь создает проблему - необходимо ее поддерживать, иначе умрешь...

Ты пишешь несусветную глупость. Нестатический метод - это такая функция, первый аргумент которой всегда указатель на объект класса. У константных методов этот указатель константный. Все. Вдолби это себе в голову и твоя универсальная формула начнет работать.
PM   Вверх
xvr
Дата 21.5.2013, 11:26 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(iipetrov @  21.5.2013,  09:39 Найти цитируемый пост)
Это создает существенную проблему: нестатический метод совершенно не обязан давать одинаковые результаты на одинаковых входных данных.

Это не проблема - это аксиома.  smile 

PM MAIL   Вверх
Alexeis
Дата 21.5.2013, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



  Суть функции члена это изменение состояния объекта. Иначе функциональщина получается какая-то.

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM ICQ Skype   Вверх
iipetrov
Дата 21.5.2013, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(bsa @ 21.5.2013,  10:53)
Ты пишешь несусветную глупость. Нестатический метод - это такая функция, первый аргумент которой всегда указатель на объект класса. У константных методов этот указатель константный.

Этот аргумент скрыт от программиста, если он и есть... Программисту С++ не важно как реализуется на низком уровне.

Статический метод не зависит от данных класса. 
Константный метод зависит от данных класса, но не меняет их.
Не константный метод делает с данными класса что угодно.

Поэтому гарантирует одинаковый выход при одинаковом входе только статический метод. Исключение - случай когда все методы константные, или когда вообще нет данных.

Где конкретно у меня написана глупость?



PM MAIL   Вверх
Guinness
Дата 21.5.2013, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(iipetrov @  21.5.2013,  13:08 Найти цитируемый пост)
Где конкретно у меня написана глупость?

Боюсь, что везде. Вы же не отличаете данные класса от данных экземпляра класса.
PM MAIL   Вверх
iipetrov
Дата 21.5.2013, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Guinness @ 21.5.2013,  13:26)
Цитата(iipetrov @  21.5.2013,  13:08 Найти цитируемый пост)
Где конкретно у меня написана глупость?

Боюсь, что везде. Вы же не отличаете данные класса от данных экземпляра класса.

Еще как отличаю. Я ничего еще про экземпляры не говорил. Это отдельная проблема.
Не надо цепляться к словам. Имелись в виду именно данные экземпляра класса.

Это сообщение отредактировал(а) iipetrov - 21.5.2013, 13:38
PM MAIL   Вверх
math64
Дата 21.5.2013, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



iipetrov, код у тебя не C++, а  C# или Java.
Не статический метод может делать с полями класса что угодно, но это не значит что он должен это делать.
Обычно перед объявлением метода описывается, что он делает - и он должен делать именно это.
При оформлении этих комментариев по специальным правилам из файла исходников можно создать файл документации.
Пользователю твоего класса прочитавшему твою документацию, должно быть ясно что метод делает. А про private-поля он не должен думать.
PM   Вверх
iipetrov
Дата 21.5.2013, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(math64 @ 21.5.2013,  13:38)
Пользователю твоего класса прочитавшему твою документацию, должно быть ясно что метод делает. А про private-поля он не должен думать.

Юзеру надо постоянно помнить в каком же состоянии находится экземпляр класса. А состояние именно в private-полях (то есть юзер фактически не знает его). Это рано или поздно приведет к ошибкам.
К тому же сплошь и рядом классы плохо документируются, и даже исходник класса отсутствует.


Это сообщение отредактировал(а) iipetrov - 21.5.2013, 13:43
PM MAIL   Вверх
Guinness
Дата 21.5.2013, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(iipetrov @  21.5.2013,  13:35 Найти цитируемый пост)
 Я ничего еще про экземпляры не говорил

Цитата(iipetrov @  21.5.2013,  13:35 Найти цитируемый пост)
Имелись в виду именно данные экземпляра класса.

Цитата(iipetrov @  21.5.2013,  13:35 Найти цитируемый пост)
Не надо цепляться к словам.

Если не цепляться, то не понятно о чем Вы говорите.
Цитата(iipetrov @  21.5.2013,  13:35 Найти цитируемый пост)
Еще как отличаю. Я ничего еще про экземпляры не говорил. Это отдельная проблема.

Какая?
PM MAIL   Вверх
iipetrov
Дата 21.5.2013, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Guinness @ 21.5.2013,  13:43)
Цитата
Это отдельная проблема.

Какая?

В программе есть множество экземпляров, которые вроде бы представляют одно и то же, а на самом деле совершенно различны. Это тоже может привести к ошибкам.

Это сообщение отредактировал(а) iipetrov - 21.5.2013, 13:48
PM MAIL   Вверх
Guinness
Дата 21.5.2013, 13:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(iipetrov @  21.5.2013,  13:47 Найти цитируемый пост)
В программе есть множество экземпляров, которые вроде бы представляют одно и то же, а на самом деле совершенно различны. Это тоже может привести к ошибкам.

Вы всетаки разберитесь, что такое класс, а что такое его экземпляр. И чем они отличаются. Хотя бы на интуитивно понятном примере класса User, у которого, к примеру, есть атрибуты login и pswd.
Или если Вы это понимаете, то я не понимаю про какие ошибки Вы говорите. Приведите пример.
PM MAIL   Вверх
iipetrov
Дата 21.5.2013, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Guinness @ 21.5.2013,  13:54)
Цитата(iipetrov @  21.5.2013,  13:47 Найти цитируемый пост)
В программе есть множество экземпляров, которые вроде бы представляют одно и то же, а на самом деле совершенно различны. Это тоже может привести к ошибкам.

Вы всетаки разберитесь, что такое класс, а что такое его экземпляр.Или если Вы это понимаете, то я не понимаю про какие ошибки Вы говорите. Приведите пример.

Паттерн Singleton не зря же придумали. Это попытка решить описанную проблему ООП.

Это сообщение отредактировал(а) iipetrov - 21.5.2013, 14:01
PM MAIL   Вверх
math64
Дата 21.5.2013, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Классы без полей - это экзотический случай, у нормальных классов есть хотя бы одно поле, и это никак не нарушает парадигму ООП - где-то состояние объеков же надо хранить, без этого никак.
А вот если ты не пишешь документацию (хотя бы давая говорящие имена методам), а тем более изменяя метод, и не отражаешь это в документации - это действительно нарушение принципов ООП.
Относительно лишних полей:
Код

class A {
public:
  int getX() { return x; }
private:
  int x;
};

class B {
public:
  A getA() { return a; }
  int getX() { if(<оптимизация>) x = a->getX(); return x; }
private:
  A* a;
  int x; // Вот это поле действительно лишнее - можно всегда получить его из a->getX()
};



Это сообщение отредактировал(а) math64 - 21.5.2013, 14:06
PM   Вверх
iipetrov
Дата 21.5.2013, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



math64
private-поля никогда не отражаются в документации. 
public-метод может выполнить свою функциональность, описанную в документацию, и поменять private-поля. 
Это может отразится на работе всех остальных методов класса.

Это сообщение отредактировал(а) iipetrov - 21.5.2013, 14:13
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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