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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Описание указателей? Синтаксис описания указателей 
:(
    Опции темы
BlHol
Дата 3.5.2006, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Добрый день!
Пытался задать этот вопрос в теме про указатели, но никто не отвечает, а нужно сильно срочно
Итак.
Маленький вопрос:

Такой код:
Код

TComponent *Obj = (TComponent *)Sender;



Первая часть (до "=") понятна:  указатель на объект класса.


А вот это как понимать?:
 
Код

(TComponent *)Sender;


Заранее благодарен.
С уважением.  
 
PM MAIL   Вверх
likehood
Дата 3.5.2006, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


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

Репутация: 8
Всего: 24



вообще-то, лучше так:
Код

TComponent *obj = dynamic_cast<TComponent*>(Sender);

то что справа от = это приведение указателя Sender к типу TComponent*. Это необходимо, поскольку Sender объявлен как TObject* Sender. Надо чтобы типы справа и слева от = совпадали, или неявно приводились один к другому. В данном случае неявное приведение невозможно, поэтому мы делаем его явно. Второй способ лучше, поскольку оператор dynamic_cast проверяет возможность приведения типа, а если оно невозможно, возвращает NULL. 
PM MAIL   Вверх
adonin
Дата 3.5.2006, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 16.12.2005
Где: Новочеркасск Рост овская обл.

Репутация: 2
Всего: 5



Это привидение типа. Я могу предположить (так как не вижу кода), что Sender - переменная типа void * 
Компилятор не позволит присвоить переменной с типом TComponent * значение переменной с типом void *. Хотя, и тот и тот тип  - это указатели, и занимают по 4 байта.
Чтобы сказать компилятору, что вы всё таки хотите выполнить такое присвоение, вы должны переопределить тип переменной Sender:
(Новый_тип)Переменная
В качестве нового типа вы указываете: Указатель на TComponent.  
--------------------
Тот, кто слизывает мед с крапивы, платит за него слишком дорого. (Томас ФУЛЛЕР)
PM MAIL   Вверх
Fazil6
Дата 3.5.2006, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата

А вот это как понимать?:

это называется приведение типа, т.е. в данном выражении считать Sender указателем на TComponent 
PM MAIL   Вверх
adonin
Дата 3.5.2006, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 16.12.2005
Где: Новочеркасск Рост овская обл.

Репутация: 2
Всего: 5



Пока писал, ответили  smile  
--------------------
Тот, кто слизывает мед с крапивы, платит за него слишком дорого. (Томас ФУЛЛЕР)
PM MAIL   Вверх
Любитель
Дата 3.5.2006, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Программист-романтик
****


Профиль
Группа: Комодератор
Сообщений: 3645
Регистрация: 21.5.2005
Где: Воронеж

Репутация: 24
Всего: 92



Судя по всему имеем:
1. TObject* sender (или какой там класс, суть в том, что TComponent - наследник TObject)
2. Хотим вызвать метод или обратиться к полю из TComponent (не TObject)
3. Знаем, что фактически sender указывает на экземпляр класс TComponent
Что делаем:
    (TComonent*) sneder - просто приводим к типу указателя на TComponent

ЗЫ Хотя лучше юзать reinterpret_cast 


--------------------
PM MAIL ICQ Skype   Вверх
Fazil6
Дата 3.5.2006, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата

ЗЫ Хотя лучше юзать reinterpret_cast 

чем же лучше? dynamic_cast надо использовать 
PM MAIL   Вверх
cozzzy
Дата 3.5.2006, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 29.4.2006
Где: Харьков

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



Цитата(Любитель @  3.5.2006,  12:40 Найти цитируемый пост)
ЗЫ Хотя лучше юзать reinterpret_cast 

Не правда. 
Если каст делается в от родителя к наследнику. то юзается dynamic_cast

reinterpret_cast использовался бы, если sender - void* 
PM MAIL   Вверх
MAKCim
Дата 3.5.2006, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


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

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



Цитата

Если каст делается в от родителя к наследнику. то юзается dynamic_cast

dynamic_cast используется при приведении указателя/ссылки 
на объект полиморфного базового класса к производному
Цитата

Компилятор не позволит присвоить переменной с типом TComponent * значение переменной с типом void *

если речь о C++  smile 
Цитата

reinterpret_cast использовался бы, если sender - void*  

зачем тогда reinterpret_cast? Лучше static_cast (если точно знаешь что void* Sender указывает на TComponent) 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
cozzzy
Дата 3.5.2006, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 29.4.2006
Где: Харьков

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



Как раз для void* самое лучшее приведение - reinterpet_cast

Основное назначение static_cast - приведение простых типов вроде int->char, float->double 
PM MAIL   Вверх
LuckLess
Дата 4.5.2006, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(cozzzy @  3.5.2006,  20:56 Найти цитируемый пост)
Основное назначение static_cast - приведение простых типов вроде int->char, float->double  


ерунда.
static_cast единственно правильное решение для преобразования родитель - потомок , если уверен, что оно возможно.
dynamic_cast если не уверен. вообще dynamic_cast лучше не использовать.

вот попробуй примерчик.
Код

#include <iostream>

class A
   {
   int g[100];
   };
class B{};
class C:public A,public B{};


void main (void)
   {
   B* a = new C;
   std::cout << reinterpret_cast<C*>(a) << "\n"
            << static_cast<C*>(a);
   }

dynamic_cast тоже даст правельный результат, но зато убъет больше времени(значительно больше) + требует RTTI. 
PM MAIL   Вверх
LuckLess
Дата 4.5.2006, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



вот примерчик на все преобразования, кому интересно.
Код

#include <iostream>

class B
   {
   int GG[100];
   public:
   virtual ~B(){};
   };

class C
   {
   public:
   virtual ~C(){};
   };

class A:public B,public C{};


void main (void)
   {
   C* c = new A;
   typedef A* pA;
   std::cout << reinterpret_cast<A*>(c) << "\n"
      << static_cast<A*>(c) << "\n"
      << dynamic_cast<A*>(c) << "\n"
      << (A*)c << "\n"
       << pA(c) << "\n";
   }

Но только не подумайте, что преобразования в стиле С безопасны.
Они в разных случаях ведут себя по разному. 
PM MAIL   Вверх
MAKCim
Дата 4.5.2006, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


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

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



Цитата

dynamic_cast тоже даст правельный результат

в данном случае даже не скомпилируется   smile 
еще раз
Цитата

dynamic_cast используется при приведении указателя/ссылки 
на объект полиморфного базового класса к производному
 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
LuckLess
Дата 4.5.2006, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(MAKCim @  4.5.2006,  16:57 Найти цитируемый пост)
в данном случае даже не скомпилируется  

ох. прям сложно сделать так чтоб скомпилировался?
и к томуже во втором примере я дал компилябельный вариант. 
PM MAIL   Вверх
MAKCim
Дата 4.5.2006, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


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

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



Цитата

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

для каждого случая свой вариант преобразования
в случае неполиморфных классов (предок-потомок) - static_cast, в случае несвязанных никаким отношением классов - reinterpret_cast, в случае полиморфных - dynamic_cast
в твоем компилируемом варианте в общем случае безопасен только dynamic_cast
потому как в случае
Код

C* c=new C;
...
A* a=static_cast<A*>(c);

в a будет адрес предположительно (думает компилятор  smile ) объекта класса A, что не верно
dynamic_cast вернет 0 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
LuckLess
Дата 4.5.2006, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(MAKCim @  4.5.2006,  19:24 Найти цитируемый пост)
в случае полиморфных - dynamic_cast

нет. dynamic_cast применяться не в случае полиморфизма, а в случае кода полиморфизм не вышел, и когда надо срочно сдавать проект а переделывать нету времени.
dynamic_cast убивает полиморфизм как понятие.

а static_cast работает одинаково как с полиморфнами типами, так и нет. 
хотя приведение предок - потомок в любом случае - ошибка стадии проектирования, но static_cast меньшая ошибка нежели dynamic , поскольку последний не просто гробит полиморфизм как понятие, но еще и тащит за собой тяжолую библиотеку + подторжаживает систему. 
PM MAIL   Вверх
MAKCim
Дата 4.5.2006, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


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

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



Цитата

а static_cast работает одинаково как с полиморфнами типами, так и нет. 

см. мой предыдущий пост, не во всех случаях
Цитата

dynamic_cast убивает полиморфизм как понятие.

если неправильно применять, то любое средство языка гробит функциональность, для реализации которой оно вводилось
вообще dynamic_cast - полезная вещь, но, естественно все должно быть по делу   


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
LuckLess
Дата 4.5.2006, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



пф. спорить чуствуеться бесполезно.

Цитата(MAKCim @  4.5.2006,  21:08 Найти цитируемый пост)
см. мой предыдущий пост, не во всех случаях

и что? что в том посте то? брр.
ясное дело что если робитель - не потомок, то статик каст наделает бед , также и реинтрепрет. не в этом дело совсем.
Это совершенно не означает что надо использовать динамик. если я точно знаю что родитель - на самом деле потомок - надо использовать статик и точка.


Цитата(MAKCim @  4.5.2006,  21:08 Найти цитируемый пост)
если неправильно применять, то любое средство языка гробит функциональность, для реализации которой оно вводилось
вообще dynamic_cast - полезная вещь, но, естественно все должно быть по делу    

Как динамик каст не применяй - он гробит ООП.
можно сказать что динамик каст в ООП - это goto в структурном программировании 
PM MAIL   Вверх
cozzzy
Дата 4.5.2006, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 29.4.2006
Где: Харьков

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



Цитата(LuckLess @  4.5.2006,  20:30 Найти цитируемый пост)
Как динамик каст не применяй - он гробит ООП.можно сказать что динамик каст в ООП - это goto в структурном программировании 


Цитата Bruce Eckel "Thinking in C++, vol.2":
Цитата

For most programs downcasting is unnecessary, and is actually discouraged, since everyday polymorphism solves most problems in object-oriented application programs. However, the ability to check a cast to a more derived type is important for utility programs such as debuggers, class browsers, and databases. C++ provides such a checked cast with the dynamic_cast operator


Добавлено @ 21:56 
И еще из MSDN:

Цитата

In general you use static_cast when you want to convert numeric data types such as enums to ints or ints to floats, and you are certain of the data types involved in the conversion. static_cast conversions are not as safe as dynamic_cast conversions, because static_cast does no run-time type check, while dynamic_cast does. A dynamic_cast to an ambiguous pointer will fail, while a static_cast returns as if nothing were wrong; this can be dangerous.
 
PM MAIL   Вверх
LuckLess
Дата 4.5.2006, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(cozzzy @  4.5.2006,  21:54 Найти цитируемый пост)
debuggers, class browsers, and databases

да яне спорю что иногда. оооочень редко динамик каст можно применить, но говорить в этом случая о полиморфизме нельзя!


Цитата(cozzzy @  4.5.2006,  21:54 Найти цитируемый пост)
static_cast returns as if nothing were wrong; this can be dangerous.

я и говорю, что статик надо использовать только кодга знаешь что родитель - потомок.  
PM MAIL   Вверх
MAKCim
Дата 4.5.2006, 22:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


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

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



Цитата

Это совершенно не означает что надо использовать динамик. если я точно знаю что родитель - на самом деле потомок - надо использовать статик и точка.

еще раз говорю, не всегда
Код

class A 
{
public:
    virtual ~A() {}
};

class B
{
public:
    virtual ~B() {}
};

class C {};

class D: public C, virtual public A, virtual public B
{
};

int main()
{
    A* a=new D;        // точно знаю, что родитель - потомок
    D* d=static_cast<D*>(a);      // не катит (в compile-time недостаточно информации)
    D* p=dynamic_cast<D*>(a);  // OK
    return 0;
} 

кстати, этот пример опрвергает Ваше утверждение
Цитата

а static_cast работает одинаково как с полиморфнами типами, так и нет. 

Цитата

Как динамик каст не применяй - он гробит ООП.
можно сказать что динамик каст в ООП - это goto в структурном программировании  

Вы не задавались вопросом, зачем он тогда вообще нужен?
и вообще
dynamic_cast - неотъемлимая часть RTTI, RTTI в общем случае нужен и оправдан т к (см. Дизайн и эволюция C++ ст. 321-322) => dynamic_cast как механизм RTTI оправдан и не надо его сравнивать с goto, который всегда можно заменить в коде и который делает этот код менее понятным
dynamic_cast нужен не только ради реализации подобного кода, который несомненно плох и применение в нем dynamic_cast неоправдано
Код

class A {...}; // полиморфный
class B: public A {...};
class C: public A {...};
...

void F(A* a)
{
    if (dynamic_cast<B*>(a)) {...}
   else if (dynamic_cast<C*>(a)) {...}
   else ...
}
 

ps. спор действительно бесполезный  

Это сообщение отредактировал(а) MAKCim - 4.5.2006, 22:44


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
LuckLess
Дата 4.5.2006, 22:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(MAKCim @  4.5.2006,  22:35 Найти цитируемый пост)
ps. спор действительно бесполезный  

:yes:
согласен с goto перебрал smile smile.
просто хочу сказать что надо стараться не использовать rtti и динамик каст если это возможно, а чаще всего это возможно.

 
PM MAIL   Вверх
cozzzy
Дата 4.5.2006, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 54
Регистрация: 29.4.2006
Где: Харьков

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



Цитата(LuckLess @  4.5.2006,  21:56 Найти цитируемый пост)
просто хочу сказать что надо стараться не использовать rtti и динамик каст если это возможно, а чаще всего это возможно.

Возможно на счет использования dynamic_cast ты и прав, но чем тебе в целом RTTI не угодил? 
PM MAIL   Вверх
LuckLess
Дата 5.5.2006, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



rtti в большинстве своем нарушает принципы ООпП.
да и медленный он..
 
PM MAIL   Вверх
Kostt
Дата 5.5.2006, 07:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 169
Регистрация: 8.1.2006
Где: Томск

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



RTTI во многих случаях просто необходим. А самому его реализовывать - еще медленнее будет. Так что спор ни о чем. 
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0697 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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