Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Почему в базовом классе нельзя делать данные открытыми?  (Прочитано 8170 раз)
0 Пользователей и 1 Гость смотрят эту тему.
USBLexus
Опытный

ru
Offline Offline
Пол: Мужской
Кот рыжий


« : 22-04-2005 02:00 » 

Я оставил поле данных в базовом классе типа CString как public, затем унаследовал его несколькими потомками изменяя в каждом значение этого поля, программу не приняли потому что в базовом классе данные как public В чем ошибка то?
Записан

#define QUESTION(b) (2*b)||(!(2*b)) (c) William Shakespeare
vasyav
Гость
« Ответ #1 : 22-04-2005 06:44 » 

Если расматривать теорию, то это нарушение инкапсуляции. Манипуляции с данными в классе должны идти через методы класса.

Другими словами ты как разработчик класса не смошеж гарантировать содержимое поля и соответсвенно состояние твоего класса после наследования.
Записан
USBLexus
Опытный

ru
Offline Offline
Пол: Мужской
Кот рыжий


« Ответ #2 : 22-04-2005 06:53 » 

Если расматривать теорию, то это нарушение инкапсуляции. Манипуляции с данными в классе должны идти через методы класса.

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

Так я специально так сделал чтобы после наследования это поле было удобно менять не перегружая его
Записан

#define QUESTION(b) (2*b)||(!(2*b)) (c) William Shakespeare
vasyav
Гость
« Ответ #3 : 22-04-2005 07:10 » 

поля не перегружаться. Поля - это типа состояние обьекта твоего класса.

ЗЫ: Ключевое слово в моем посте инкапсуляции данных.

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

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

Теперь представь тебе нужно будет просмотреть весь исходник и найти все места которые изменяют зн. этого метода. Вместо того что б только подправить реализацию метода который записывает ее зн.

ЗЫ: Видать ты не понял сути ООП.
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #4 : 22-04-2005 07:21 » 

USBLexus, если они тебе в производных классах нужны, то сделай их protected.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
vasyav
Гость
« Ответ #5 : 23-04-2005 11:04 » 

2Джон: Да можно зделать и протектед. Но помойму не в этом вопрос. Вопрос почему нельзя их делать public
Записан
michaelprog
Гость
« Ответ #6 : 24-04-2005 14:03 » 

Не НЕЛЬЗЯ, а НЕПОЛОЖЕНО.
НЕЛЬЗЯ - это когда компилятор код не кушает,
а НЕПОЛОЖЕНО - это когда заказчик не принимает работу, т.е. прога работает, но нарушены базовые концепции все того-же ООП.
Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 25-04-2005 12:27 » 

USBLexus,

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

Примеры проблем:

1.  Смена типа хранимого значения в будущих релизах.  Например, некоторое поле хранили как int, а затем решили из каких-то соображений, что данное поле удобнее хранить как структуру.   Если поле видно извне класса, то это потребует перекомпиляции пользовательского кода, если же пользователи могут работать только через специальные функции get/set (или properties в С#), то в новой версии достаточно переписать get/set и поставить новую dll для пользователей.

2.  Многопотоковое приложение. В многопотоковых приложениях прямой доступ к полям требует явного использования блокировок, что чревато ошибками (забывают про блокировки или используют избыточные блокировки). При использовании get/set можно внедрить неявные блокировки внутрь методов, что упрощает разработку и отладку софта, использующего класс.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
USBLexus
Опытный

ru
Offline Offline
Пол: Мужской
Кот рыжий


« Ответ #8 : 03-05-2005 04:57 » 

Ладно убедили)))) Все закрою))

Тогда у меня такой вопрос
Например в билдере и дельфи есть такая вещь как property -
задаешь там переменную и автоматически создаются 2 функции - Get и Set есть ли в VC что либо подобное?
Записан

#define QUESTION(b) (2*b)||(!(2*b)) (c) William Shakespeare
Alf
Гость
« Ответ #9 : 03-05-2005 06:25 » 

Это нестандартное расширение языка (впрочем,как и у Borland). Введено для поддержки свойств объектов COM, но может применяться и самостоятельно.

Синтаксис:

Код:
__declspec(property(get=get_func, put=put_func)) prop_type prop_id;

get_func и put=put_func - методы для доступа к переменной, хранящей состояние свойства; если свойство должно быть только на чтение/запись, соответствующее объявление не используется.

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

ru
Offline Offline
Пол: Мужской
Кот рыжий


« Ответ #10 : 03-05-2005 06:34 » 

А как ей пользоваться? Можно пример?
Записан

#define QUESTION(b) (2*b)||(!(2*b)) (c) William Shakespeare
Alf
Гость
« Ответ #11 : 03-05-2005 07:06 » 

Вот фрагмент из работающего проекта. Лишнее выкинул для экономии места.

Файл AmaPack102.h:

Код:
class CServiceInfo: public CPack
{
...
public:
  bool Get_F_RedBook(void);
  __declspec(property(get=Get_F_RedBook)) bool F_RedBook;
...
};

Файл AmaPack102.cpp:

Код:
#include "AmaPack102.h"
...
bool CServiceInfo::Get_F_RedBook(void)
{
  return (PackPtr->F_RedBook);
}

В результате мой класс CServiceInfo приобретает свойство F_RedBook, доступное только для чтения. Примера свойства, доступного для записи, под рукой не нашлось, но это не сложнее. Разумеется, с тем же успехом можешь вызвать метод Get_F_RedBook, фактически именно этот вызов и подставляется при обращении к значению свойства.
Записан
USBLexus
Опытный

ru
Offline Offline
Пол: Мужской
Кот рыжий


« Ответ #12 : 04-05-2005 08:16 » 

Ok спасибо! Очень ценная информация для меня!
Записан

#define QUESTION(b) (2*b)||(!(2*b)) (c) William Shakespeare
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines