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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: геттеры сеттеры в VC60  (Прочитано 6401 раз)
0 Пользователей и 1 Гость смотрят эту тему.
alxmobile
Гость
« : 04-07-2006 12:41 » 

Как в Visual C++ реализовать геттеры и сеттеры классов? Есть ли стандартный механизм?
Я попробовал так, но при комиляции возникла ошибка:
Код:
class clsSlave
{
  friend class clsMaster;
public:
  clsSlave();
  int operator =(int);
  operator int();

protected:
  int (*Set)(int);
  int (*Get)();
};
clsSlave::clsSlave()               { Set = 0; Get = 0; }
int clsSlave::operator =(int src)  { return Set ? (*Set)(src) :src; }
    clsSlave::operator   int()     { return Get ? (*Get)()    :0  ; }

class clsMaster
{
public:
  clsMaster();
  clsSlave & Variable();

private:
  int varSet(int);
  int varGet();
 
  clsSlave varSlave;
};
clsSlave & clsMaster::Variable() {return varSlave;}

clsMaster::clsMaster()
{
  varSlave.Set = varSet;  // Ошибка: несоответствие типов
  varSlave.Get = varGet;  //
}

int main(int argc, char* argv[])
{
  clsMaster master;
  master.Variable() = 5;

  int test = master.Variable();
  return 0;
}
Скромно так... Помогите, пожалуйста, начинающему VC-програмеру.
Записан
ysv_
Помогающий

ua
Offline Offline

« Ответ #1 : 06-07-2006 10:20 » 

1. Ошибка возникает потому что, clsSlave::Set имеет тип int (*)(int), а clsMaster::varSet имеет тип int (clsMaster::*)(int).
Вот пример кода, обходящего эту ошибку:
Код:
class clsMaster;

class clsSlave

  friend class clsMaster;
public: 
  clsSlave(clsMaster* master): Set(0), Get(0), mMaster(master) {}
  int operator=(int); 
  operator int();

protected: 
  int (clsMaster::*Set)(int); 
  int (clsMaster::*Get)();

private:
  clsMaster* mMaster;
};

int clsSlave::operator=(int src) 
{
  return Set ? (mMaster->*Set)(src): src;
}   

clsSlave::operator int()     
{
  return Get ? (mMaster->*Get)(): 0;
}

class clsMaster
{
public:
  clsMaster(); 
  clsSlave& Variable();
private: 
  int varSet(int); 
  int varGet();   
  clsSlave varSlave;
};

clsSlave& clsMaster::Variable()
{
  return varSlave;
}

clsMaster::clsMaster(): varSlave(this)

  varSlave.Set=varSet;  // Ошибка: несоответствие типов 
  varSlave.Get=varGet;  //
}

int main(int argc, char* argv[])

  clsMaster master; 
  master.Variable()=5; 
  int test=master.Variable(); 
  return 0;
}
Записан
ysv_
Помогающий

ua
Offline Offline

« Ответ #2 : 06-07-2006 10:50 » 

А вот так это можно реализовать для поддержки Setter и Getter'ов любого типа (используя тэмплейты):
Код:
template <class Type, class Holder> class TypeProxy

public: 
  typedef void (Holder::*Setter)(Type);
  typedef Type (Holder::*Getter)();
  TypeProxy(Holder* holder, Setter setter, Getter getter):
    mSetter(setter), mGetter(getter), mHolder(holder)
  {
  }

  TypeProxy& operator=(Type t)
  {
    printf("Type t=%d\n", t);
    (mHolder->*mSetter)(t);
    return *this;
  }

  operator Type() {return (mHolder->*mGetter)();}

private:
  Holder* mHolder;
  Setter mSetter;
  Getter mGetter;
};

class Test
{
public:
  Test(): mVar(this, varSet, varGet), mProp(0) {} 
  TypeProxy<int, Test>& prop() {return mVar;}

private: 
  TypeProxy<int, Test> mVar;

  void varSet(int t) {mProp=t;} 
  int varGet() {return mProp++;}   
  int mProp;
};

int main(int argc, char* argv[])

  Test test; 
  int b=test.prop(); 
  test.prop()=5; 
  return 0;
}
« Последнее редактирование: 06-12-2007 19:00 от Алексей1153++ » Записан
alxmobile
Гость
« Ответ #3 : 06-07-2006 11:53 » 

2ysv_:
Спасибо! Не предполагал такой тонкости в отличии типов.
Уже создал рабочий пример, и теперь пытаюсь его усовершенствовать.
О тэмплейтах уже успел подумать, но думать об этом было страшно. Улыбаюсь
После Вашего второго поста уже не так страшно.
Ещё раз спасибо.
Записан
alxmobile
Гость
« Ответ #4 : 25-05-2007 21:20 » 

Здравствуйте! Освоение C++ пришлось оставить почти на год. И вот, я решил снова поднять незавершённую тему.

В предыдущих примерах мне не нравится вид конструкции
Код:
int b=test.prop();  
test.prop()=5; 
Хочется видеть что-то типа
Код:
int b=test.prop;
test.prop=5;
К тому же, это решение неоптимально с точки зрения использования RAM.
Пытаясь исправить эти недостатки, я написал такой код:
Код:
class clsTest;

template < class clsParent, class clsType, int(clsTest::*fncSetter)(int), int(clsTest::*fncGetter)() > class clsSetGet
{
  friend clsParent;
public:
  clsType operator = (clsType p){ return mParent.propSet(p);}
  operator clsType()            { return mParent.propGet(); }
private:
  clsParent & mParent;
  clsSetGet(clsParent & parent): mParent(parent)  {}
};

class clsTest
{
public:
  int propVal;
  int propSet(int p){return propVal=p;}
  int propGet()     {return propVal;}

  clsSetGet< clsTest, int, propSet, propGet > prop;

  clsTest(): prop(*this), propVal(0) {}
};

int main(int argc, char* argv[])

  int b;
  clsTest test;

  test.prop = 7;
  b = test.prop;


  return 0;
}
Но так как я ещё плохо разобрался с шаблонами, то  во-первых, код не работает. А во-вторых, в строке
Код:
template < class clsParent, class clsType, int(clsTest::*fncSetter)(int), int(clsTest::*fncGetter)() > class clsSetGet
хочется избавиться от упоминания 'int' и 'clsTest', а в строках
Код:
clsType operator = (clsType p){ return mParent.propSet(p);}
operator clsType()            { return mParent.propGet(); }
не упоманать 'propSet' и 'propGet'.

Как правильно реализовать этот пример?
Желательно, чтобы в clsSetGet запоминалась бы минимальная информация.
« Последнее редактирование: 25-05-2007 21:24 от alxmobile » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines