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

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

ua
Offline Offline

« : 19-11-2009 20:22 » 

Объясните, как можно реализовать данную задумку. Есть, к примеру, следующий класс:
Код:
extern int f(int value);
class A
{
int m_value;
public:
void SetValue(int value){m_value=f(value);}
int GetValue()const{return m_value;}
};
Хотелось бы организовать чтение и изменение значение члена-класса m_value через одну функцию, что-нибудь на подобиe:
Код:
A a;
a.Value():=3;
Как это можно сделать???
« Последнее редактирование: 19-11-2009 20:32 от Sel » Записан
Вад
Модератор

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

« Ответ #1 : 19-11-2009 21:03 » new

Код:
class A
{
int m_value;
public:
int& Value() { return m_value; }
};
но подобные решения лучше использовать аккуратно: отдавать наружу ссылку на внутренний член - прямое нарушение инкапсуляции. Даже если завернуть переменную во что-нибудь типа
Код:
template <typename T>
class Wrapper
{
private:
    T& ref_;
public:
    Wrapper(T& ref) : ref_(ref){}
    operator T () const { return ref_; }
    operator= (const T& value) { ref_ = value; }
}

class A
{
private:
    int m_value;
public:
    Wrapper<A> Value(){ return Wrapper<A>(m_value); }
}
всё равно отдаёт чем-то нездоровым Улыбаюсь

Другое дело, что, скажем, std::vector именно подобным образом (первым, а не вторым Улыбаюсь ) реализует operator[].
« Последнее редактирование: 19-11-2009 21:05 от Вад » Записан
grb1zli
Интересующийся

ua
Offline Offline

« Ответ #2 : 19-11-2009 22:02 » 

Дело в том, что выбросить просто ссылку не получиться, поскольку при вызыве функции SetValue() должна вызываться еще одна функция...
Записан
Вад
Модератор

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

« Ответ #3 : 19-11-2009 22:17 » 

А, извиняюсь за невнимательность. Тогда - что-то вроде второго варианта, этакий адаптер. Там ведь в operator= можно что угодно вызывать.

Хотя я бы на твоём месте задумался: поведение, когда в переменную устанавливается одно значение, а на деле там оказывается совсем другое, едва ли можно назвать присваиванием. То есть, синтаксис присваивания в данном случае вводит в заблуждение.
« Последнее редактирование: 19-11-2009 22:19 от Вад » Записан
grb1zli
Интересующийся

ua
Offline Offline

« Ответ #4 : 19-11-2009 22:45 » 

Согласен!
Я наверное не совсем удачный пример привел, на самом деле объявление класса имеет следующий вид:
Код:
typedef cCell* PCell;
class cTable
{
protected:
ULONG m_maxRows;//ограничение на количество строк
ULONG m_maxColums;//ограничение на количество столбцов
std::vector<PCell> m_cells;//вектор ячеек
protected:
void deleteCell(ULONG seqNum);//удаляет ячейку из массива ячеек с порядковым номером seqNum
void addCell(const cRectOfCell& rectOfCell);//добавляет ячейку в массив ячеек
public:
//Конструкторы и деструктор
cTable(ULONG maxRows=1,ULONG maxColums=1);
virtual ~cTable(void);
cTable(const cTable& table);
//Пользовательский интерфейс
ULONG GetMaxRows(void)const{return m_maxRows;}
            void SetMaxRows(ULONG maxRows);
ULONG GetMaxColums(void)const{return m_maxColums;}
            void SetMaxColums(ULONG maxColums);
size_t GetSizeOfCellsVector(void)const{return m_cells.size();}
const cCell& operator[](ULONG seqNum)const{return *m_cells[seqNum];}//возвращает ячейку с порядковым номером
std::string& operaor()(ULONG row,ULONG colum);
//...
};
Думаю понятно, для чего нужен этот класс
А объединить я хотел функции SetMaxColums и GetMaxColums, но дело в том, что при вызове SetMaxColums из вектора ячеек должны удаляться все ячейки, которые выходят за таблицу
Записан
Вад
Модератор

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

« Ответ #5 : 19-11-2009 22:52 » 

Теперь понятно. Я придерживаюсь взгляда, что size() - отдельно, а resize() - отдельно. Всё-таки, изменение при resize серьёзное, тут лучше явно развести методы, кабы чего случайно не вышло Улыбаюсь

В другом случае возможно, и посоветовал бы подход с адаптером (это если в нагрузку какое-нибудь кэширование производится, или ещё какое-нибудь более-менее безобидное побочное действие).
« Последнее редактирование: 19-11-2009 22:54 от Вад » Записан
grb1zli
Интересующийся

ua
Offline Offline

« Ответ #6 : 19-11-2009 22:57 » 

"Не буду огород городить"-Оставлю все как есть!
Спасибо за помощь Ага
Записан
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #7 : 21-12-2009 17:40 » 

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

Код:
extern int f(int value);
class A
{
    int m_value;
    public:
    void Value(int value){m_value=f(value);}
    int Value()const{return m_value;}
};

вызов:
Код:
A a();

a.Value(5);   // set
int b = a.Value();   // get
« Последнее редактирование: 21-12-2009 23:44 от Вад » Записан

С уважением Lapulya
grb1zli
Интересующийся

ua
Offline Offline

« Ответ #8 : 21-12-2009 22:10 » 

Ну вообще угадал!)Подсмотрел это в Делфи и решил, что так наверное будет неплохо. Потом поспрашивал, большинство сказали, что привычнее, когда методы size и resize отделены друг от друга. Судя по всему это отпечаток использования библиотеки STL.
Записан
Вад
Модератор

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

« Ответ #9 : 21-12-2009 23:51 » 

Судя по всему это отпечаток использования библиотеки STL.
Не совсем. Скорее, отпечаток синтаксиса C++. В C# property выглядит естественно, хотя там тоже грабли side-эффекта разбросаны щедро. Попытка сделать то же самое в C++ натыкается на необходимость танцев с бубном, поскольку встроенного механизма нет. В результате получается недостаточно очевидный, на мой взгляд, синтаксис - вроде примера с двумя методами Value(). Как по мне, лучше назвать методы более конкретными именами, раз уж их два разных.
Но тут уж кто как привык - допускаю, что если подобные подходы внедрять на уровне стиля кодирования, то в определённом кругу они будут вполне применимы.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines