Указатель на член класса
От: dalen  
Дата: 24.06.08 14:12
Оценка:
Добрый день!

есть класс Foo:


class Bar { double value; };

class Foo {
   Bar arr1[15];
   Bar arr2[12];
};


хочется получить указатель на элемент массива:

Bar Foo::*pEl;
Foo *pFoo;

pEl = &(Foo::arr1[10]); // здесь ошибка компиляции
(pFoo->*pEl).value = 12.;


как-нибудь это можно побороть?

С уважением,
Павел
Re: Указатель на член класса
От: Bell Россия  
Дата: 24.06.08 14:27
Оценка:
Здравствуйте, dalen, Вы писали:


struct Bar { double value; };

class Foo {
public:
   Bar arr1[15];
   Bar arr2[12];
};

int main()
{
   Bar (Foo::* pa)[15] = &Foo::arr1;
   
   Foo f;
   (f.*pa)[0].value = 0;

   return 0;
}


Любите книгу — источник знаний (с) М.Горький
Re[2]: Указатель на член класса
От: dalen  
Дата: 24.06.08 14:33
Оценка:
Здравствуйте, Bell, Вы писали:

Bar (Foo::* pa)[15] = &Foo::arr1;


Да, так можно сделать, но не в моем случае. У меня массивы разной длины (один 15, другой 12) — а мне надо сделать так, чтобы разыменовывался любой из массивов. И вариант
Bar *(Foo::* pa) = &Foo::arr2;
не проходит.

Паша
Re[3]: Указатель на член класса
От: Programador  
Дата: 24.06.08 15:54
Оценка: :)
Здравствуйте, dalen,

Я массив к указателю приводил

struct Obj
{  struct Mutavel
   { 
   };
   typedef Mutavel (Obj::*TMut);
   TMut parList; 
};

struct Ponto:public Obj
{  Mutavel ponto_m[3];
   Ponto()
   {  parList=reinterpret_cast <TMut>(&::Ponto::ponto_m);
   }
};

и то намучился.
Re[3]: Указатель на член класса
От: Bell Россия  
Дата: 24.06.08 16:26
Оценка: +1
Здравствуйте, dalen, Вы писали:

D>Здравствуйте, Bell, Вы писали:


D>
D>Bar (Foo::* pa)[15] = &Foo::arr1;
D>


D>Да, так можно сделать, но не в моем случае. У меня массивы разной длины (один 15, другой 12) — а мне надо сделать так, чтобы разыменовывался любой из массивов. И вариант
Bar *(Foo::* pa) = &Foo::arr2;
не проходит.



Озвуч задачу — что именно хочется получить в итоге, и для чего.
Любите книгу — источник знаний (с) М.Горький
Re: Указатель на член класса
От: Programador  
Дата: 24.06.08 16:42
Оценка:
Здравствуйте, dalen,
еще можно функций топа Bar& понаписать уквзателясм на них. тоже не очень удобно
Re: Указатель на член класса
От: Programador  
Дата: 24.06.08 17:30
Оценка:
Здравствуйте, dalen,
А лучше всего воспользоваться неизвестным хаком offsetof
Re: Указатель на член класса
От: Erop Россия  
Дата: 24.06.08 17:50
Оценка: 2 (1)
Здравствуйте, dalen, Вы писали:

D>хочется получить указатель на элемент массива:

D>как-нибудь это можно побороть?

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

Если я верно понял, что тебе надо, то можно сделать так:
class foo {
    Bar arr1[15];
    Bar arr2[12];
public:
    typedef Bar& (foo::*FieldAccessor_t)( int );

    Bar& GetArr1Elem( int i ) { assert( 0 <= i && i <= lengthof( arr1 ) ); return arr1[i]; }
    Bar& GetArr2Elem( int i ) { assert( 0 <= i && i <= lengthof( arr2 ) ); return arr2[i]; }
    
};
struct ArrayElemRef {
    foo::FieldAccessor_t getter;
    int elemIndex;
    
    Bar& Get( foo* f ) const { return (f->*getter)( elemIndex ); }
};
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: Указатель на член класса
От: dalen  
Дата: 24.06.08 19:22
Оценка:
Здравствуйте, Bell, Вы писали:

B>Озвуч задачу — что именно хочется получить в итоге, и для чего.


Есть объект, в нем атрибуты двух видов (логических) в двух массивах arr1 и arr2 условно double (на самом деле там простая надстройка над double).
Есть несколько видов операций (статических функций-членов) над парами чисел (условно функции называются f1, f2,..., fn), возвращающих bool.
Объектов много (каждой строке из базы данных соответствует объект).
Хочется дать пользователю возможность искать строки, удовлетворяющие условию. Условие — пользователь выбирает любой из атрибутов из общего множества
arr1+arr2, операцию fi, например, и второй атрибут из множества arr1+arr2. Ну и хочется в итоге написать что-то вроде:

for(iter = Objects.begin(); iter != Objects.end(); ++iter)
     if (iter->*pf(iter->*pattr1, iter->*pattr2))
         AddToView(*iter);


Павел
Re[4]: Указатель на член класса
От: dalen  
Дата: 24.06.08 19:28
Оценка:
Здравствуйте, Programador, Вы писали:

P>Я массив к указателю приводил

P>и то намучился.

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

Павел
Re: Указатель на член класса
От: Programador  
Дата: 24.06.08 19:33
Оценка:
Здравствуйте, dalen,

class Bar { double value; };

class Foo {
   Bar base[];
   Bar arr1[15];
   Bar arr2[12];
   enum {b1=arr1-base,b2=arr2-base};
};


Bar bar= Foo().base[b1+10];
Re[2]: Указатель на член класса
От: Erop Россия  
Дата: 24.06.08 19:39
Оценка:
Здравствуйте, Programador, Вы писали:

P>
P>class Bar { double value; };

P>class Foo {
P>   Bar base[];
P>   Bar arr1[15];
P>   Bar arr2[12];
P>   enum {b1=arr1-base,b2=arr2-base};
P>};
P>


P>Bar bar= Foo().base[b1+10];


Только тогда надо чтобы Foo был POD, а иначе нет гарантий При этом его можно использовать как приватное поле раального класса, или как приватного предка.
Кроме того [] -- нестандартное расширение, но в качестве base можно и arr1 использовать. Но всё равно решение плохо масштабируется на случай добавления других полей и т. д.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: Указатель на член класса
От: Кодт Россия  
Дата: 25.06.08 08:11
Оценка: :)
Здравствуйте, dalen, Вы писали:

D>хочется получить указатель на элемент массива:


Непосредственно в С++ такой фичи нет. Но!
Указатель на член класса — это разновидность функции высшего порядка, т.е. замыкания.
Поэтому можно обобщённо воспользоваться конструктором ФВП — boost::function + boost::bind.

// пусть у нас есть вот такие функции

Bar* at_arr1(Foo* host, int index) { return &host->arr1[index]; }
Bar* at_arr2(Foo* host, int index) { return &host->arr2[index]; }

// тогда

typedef boost::function<Bar*(Foo*)> foo_at;

foo_at f1 = boost::bind(at_arr1, 5);
foo_at f2 = boost::bind(at_arr2, 3);
.....
Foo foo;
f1(&foo)[2] = 123; // foo.arr1[5+2] = 123;
f2(&foo)[2] = 456; // foo.arr2[3+2] = 123;


Можно и не писать такие функции, а конструировать.
(Тут моя мысль иссякла, но надеюсь, её сейчас подхватят).
... << RSDN@Home 1.2.0 alpha rev. 655>>
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.