Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> RTTI-доступ к защищенному методу, Кто знает как 
:(
    Опции темы
Crait
  Дата 23.2.2003, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 244
Регистрация: 20.2.2003

Репутация: нет
Всего: 1



Вот возникла проблемка с вызовом TStringGrid->DrawCell() ,
а ставить RxLib не хочется...
Наверное, придется иметь дело с __closure ...
Тоже, конечно, вариант.
И править и перекомпилировать VCL тоже не хочется...
PM MAIL   Вверх
Vit
Дата 23.2.2003, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: нет
Всего: 207



RTTI работает только с Published


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Medved
Дата 23.2.2003, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 7209
Регистрация: 15.9.2002
Где: Kazakhstan, Astan a

Репутация: нет
Всего: 154



Совершенно согласен с Витом.
Но можно получить доступ в другом модуле к полям и свойствам, объявленым в published.
Для этого необходимо создать дочерний класс, на основе интересующего класса, и тогда уже, можно будет в своем модуле обращаться напрямую к тому, что объявлено в Published у родительского класса.


--------------------
http://extreme.sport-express.ru/
...и неважно сколько падал, важно сколько ты вставал...
PM MAIL WWW ICQ Skype GTalk   Вверх
Crait
Дата 24.2.2003, 07:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 244
Регистрация: 20.2.2003

Репутация: нет
Всего: 1



Про дочерний класс - это понятно.
А хотелось бы работать напрямую с компонентом.

Надеялся, что через RTTI можно доступиться не только к published.
Какой-то такой намек где-то я в help'ах видел.

Эх, придется все же установить Rx ;((
PM MAIL   Вверх
Guest
Дата 25.2.2003, 08:37 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











До protected метода можно добраться точно также, как описано в FAQ
Как добраться до protected свойства
  Вверх
Vyacheslav
Дата 25.2.2003, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



Предыдущий пост мой


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Vit
Дата 26.2.2003, 01:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: нет
Всего: 207



Цитата(Guest @ 24.2.2003, 23:37)
До protected метода можно добраться точно также, как описано в FAQ
Как добраться до protected свойства

Добраться можно, но RTTI работать так не будет...


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Vyacheslav
Дата 26.2.2003, 02:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



А причем тут RTTI. Это стандартный сиплюсплюсный прием.


--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Vit
Дата 26.2.2003, 03:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Vitaly Nevzorov
****


Профиль
Группа: Экс. модератор
Сообщений: 10964
Регистрация: 25.3.2002
Где: Chicago

Репутация: нет
Всего: 207



Цитата(Vyacheslav @ 25.2.2003, 17:36)
А причем тут RTTI.

А ты тему вопроса на всякий случай прочитай! Автор спрашивает именно про RTTI, а не о любом доступе...


--------------------
With the best wishes, Vit
I have done so much with so little for so long that I am now qualified to do anything with nothing
Самый большой Delphi FAQ на русском языке здесь: www.drkb.ru
PM MAIL WWW ICQ   Вверх
Crait
Дата 26.2.2003, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 244
Регистрация: 20.2.2003

Репутация: нет
Всего: 1



Спасибо за ссылку на статью о том как добраться до protected - свойства.
Интересная мысль, хотя и вправду несколько незаконно.
Ну а как подобным же макаром добраться до protected - метода ?
PM MAIL   Вверх
Vyacheslav
Дата 26.2.2003, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



Так ребята, признаю свою ошибку, погорячился. Добраться до проперти легче, чем до метода. Но здесь нас выручит то, что метод DrawCell() виртуальный.
Вообще -то, то что я сейчас напишу совсем противозаконно, и заниматься этим не рекомендую
Итак
Код

class TForm1 : public TForm
{
published: // IDE-managed Components
   TStringGrid *StringGrid1;
   TBitBtn *BitBtn1;
   void  fastcall BitBtn1Click(TObject *Sender);
   private: // User declarations
public:  // User declarations
   fastcall TForm1(TComponent* Owner);
  void fastcall TestDrawCell(TObject *Sender, int ACol,
         int ARow, const TRect &Rect, TGridDrawState State);

};


class TPublicGrid : public TStringGrid
{
public:
  //переопределяем виртуальный метод
  //если увидим это сообщение, у нас ничего не вышло  
  void fastcall DrawCell(int ACol, int ARow, const Windows::TRect &ARect, TGridDrawState AState
 ){ ShowMessage("protected method не вызвается");}
};



fastcall TForm1::TForm1(TComponent* Owner)
   : TForm(Owner)
{
}

void  fastcall TForm1::BitBtn1Click(TObject *Sender)
{
  //тут самый главный противозаконный акт
  TPublicGrid * Grid = (TPublicGrid*) StringGrid1;
  // Это для того, если все получится Мы получили сообщение:
  // А protected method всетаки вызвался
  StringGrid1->OnDrawCell =   TestDrawCell;
  // т.к функция виртуальная, вызовется  TStringGrid::DrawCell(),
  // а не TPublicGrid ::DrawCell()
  Grid->DrawCell(4,4, StringGrid1->CellRect(4, 4), TGridDrawState()<< gdFixed <<gdSelected );
  //возвращаем нормальную отрисовку
  StringGrid1->OnDrawCell =   NULL;
}

void fastcall TForm1::TestDrawCell(TObject *Sender, int ACol,
     int ARow, const TRect &Rect, TGridDrawState State)
{
 ShowMessage("А protected method всетаки вызвался");
}

Собрав данный проект, нажимаю на кнопку и получаю сообщение "А protected method всетаки вызвался". Что нам собственно и требовалось



Примечание Adminy: Уже достало. Если есть двойное подчеркивание, то поглатываются куски текста






--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Crait
Дата 27.2.2003, 00:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 244
Регистрация: 20.2.2003

Репутация: нет
Всего: 1



Круто.
Но незаконно-о adv/66.gif

А ты, кстати, не знаешь, на многих ли компилерах такое проходит ?

Это сообщение отредактировал(а) Crait - 27.2.2003, 00:24
PM MAIL   Вверх
Vyacheslav
Дата 27.2.2003, 00:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



Это чистый С++. Так что по идее должно пройти везде. Я стандарт не нарушал, а лишь сделал
рисковое преобразование, которое, кстати, мог выполнить и вот таким образом (без присвоения)
Код

((TPublicGrid*)StringGrid1)->DrawCell(4,4, StringGrid1->CellRect(4, 4), TGridDrawState()<< gdFixed <<gdSelected );






--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Crait
Дата 27.2.2003, 02:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 244
Регистрация: 20.2.2003

Репутация: нет
Всего: 1



Стандарт не нарушал...
Насчет синтаксиса преобразования - не сомневаюсь,
но для срабатывания обсуждаемого механизма необходимо,
чтобы индексы, соответствующие DrawCell, были одинаковыми
для VMT обоих классов.
Хотя конечно TPublicGrid и произведен от TStringGrid, но какой-нибудь
очень умный линкер может просечь, что для экземпляров
TPublicGrid кроме DrawCell ничего особо не вызывается,
т.к. в программе нет указателей TStringGrid*, которым бы присваивался адрес экземпляра TPublicGrid, так что можно
и сократить VMT у TPublicGrid, убрав оттуда все лишнее
(де-виртуализировать часть методов. Чтобы быстрее вызывались wink.gif )

Это сообщение отредактировал(а) Crait - 27.2.2003, 02:14
PM MAIL   Вверх
Vyacheslav
Дата 27.2.2003, 02:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 2124
Регистрация: 25.3.2002
Где: Москва

Репутация: 9
Всего: 59



Это было бы очень странно и являлась бы ошибкой компилятора. Очень часто делают наследование, чтобы именно и переопределить какую-либо виртуальную функцию. Если выключить виртуальность, в то нормальном стандартном случае я получу не то что хочу
В коде расположенном ниже все законно и должен вызваться TPublicGrid::DrawCell(). На минуту для простоты представим, что DrawCell() не protected у TStringGrid
Код

TPublicGrid* Grid = new TPublicGrid(this);
TStringGrid* SGrid = dynamic_cast<TPublicGrid*>(Grid);
SGrid->DrawCell(4,4, StringGrid1->CellRect(4, 4), TGridDrawState()<< gdFixed <<gdSelected );

По стандарту при вызове SGrid->DrawCell() должен быть вызван TPublicGrid::DrawCell(). А если предположить, что компилятор "де-виртуализирует" TPublicGrid (хотя я не понимаю, как это может быть), то в этом случае вызовется TStringGrid::DrawCell(), что противоречит стандарту.





--------------------
С уважением, Вячеслав Ермолаев
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0569 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.