как хранить указатели на переменные члены разных классов
От: fanruten  
Дата: 27.08.10 19:25
Оценка:
Допустим есть разные классы

class A {
public:
int a;
};

class B {
public:
int b;
};

существует ли способ в одном контенере хранить указатели на переменные члены разных классов
т.е чем должен являться some_type ?

vector<some_type>.push_back(&B::b);
vector<some_type>.push_back(&A::a);
int
Re: как хранить указатели на переменные члены разных классов
От: Vamp Россия  
Дата: 27.08.10 19:42
Оценка:
F>существует ли способ в одном контенере хранить указатели на переменные члены разных классов
F>т.е чем должен являться some_type?
Для обычных переменных (не методов) сойдет просто указатель на тип, т.е. int*.
Правда, не так, как ты написал. См. пример:

#include <vector>
using namespace std;

struct A {
   int i;
};

struct B {
   int k;
};

int main() {
   vector<int*> vec;
   A a;
   B b;
   vec.push_back(&a.i);
   vec.push_back(&b.k);
}
Да здравствует мыло душистое и веревка пушистая.
Re: как хранить указатели на переменные члены разных классов
От: wander  
Дата: 27.08.10 19:51
Оценка:
Здравствуйте, fanruten, Вы писали:

F>vector<some_type>.push_back(&B::b);

F>vector<some_type>.push_back(&A::a);

A a;
B b;
vector<int*> v;

v.push_back(&a.a);
v.push_back(&b.b);

Чем не подходит?
Re: как хранить указатели на переменные члены разных классов
От: Кодт Россия  
Дата: 27.08.10 20:05
Оценка:
Здравствуйте, fanruten, Вы писали:

F>существует ли способ в одном контенере хранить указатели на переменные члены разных классов

F>т.е чем должен являться some_type ?

F>vector<some_type>.push_back(&B::b);

F>vector<some_type>.push_back(&A::a);

Зависит от того, как эти указатели-на-члены будут использоваться.

1. Замыкая всегда на один и тот же тип MostDerived obj, где A и B — какие-то базы этого MostDerived
obj.*(vec[0]) = 123;
//Тогда банально,
typedef int MostDerived::* some_type


2. Зная ограниченное множество классов. Любой вариантный тип, например Boost.Variant
typedef int A::*aint_t;
typedef int B::*bint_t;

typedef boost::variant<aint_t, bint_t> some_type;
....
A aobj; aobj.*(boost::get<aint_t>(vec[0])) = 123;


3. Не зная вообще ничего, — любой анонимный тип, например, Boost.Any
typedef boost::any some_type;
....
aobj.*(any_cast<aint_t>(vec[0])) = 123;

можно и ващще жёстко
typedef void* some_type;
vec.push_back(new aint_t(&A::a));
...
aobj.*(*(aint_t*)vec[0]) = 123;


4. Универсальный диспетчер
struct some_type // : boost::static_visitor<int&>
{
  aint_t ai;
  bint_t bi;
  // и так далее, на весь список классов

  some_type(aint_t a, bint_t b, ...) : ai(a), bi(b), ... {}

  int& operator()(A& obj) const { return obj.*ai; }
  int& operator()(B& obj) const { return obj.*bi; }
  ....
};

vec.push_back(some_type(&A::a1, &B::b1));
vec.push_back(some_type(&A::a2, &B::b2));

A aobj; B bobj;
vec[0](aobj) = 1; // aobj.a1 = 1
vec[0](bobj) = 2; // bobj.b1 = 2

Тут, как говорится, полёт фантазии не ограничен
http://files.rsdn.org/4783/catsmiley.gif Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.