Здравствуйте, Слоноежик, Вы писали:
С>Правильный способ.
С>dynamic_cast<C*>(&a);
С> А если есть виртуальные функции то единственный. Поправьте если ошибаюсь.
А если RTTI отключен и виртуальных функций нет, то неправильный
Возможны два варианта:
1. `A` содержит один экземпляр класса `C`, неважно, путём виртуального наследования нескольких или обычным наследованием одного. Тогда static-cast или implicit-преобразование пройдут на ура.
2. `A` содержит несколько экземпляров класса `C`. Тогда компилятор будет ругаться даже на dynamic_cast (из-за этого в рантайме dynamic_cast вернет ноль).
Короче, в данном конкретном примере вообще никакого специального каста делать не нужно, компилятор сам смотрит тип аргумента функции (C*) и выполняет его. А dynamic_cast предназначен для выполнения _обратного_ преобразования, т.е. из С* получить A*.
Здравствуйте, Andrew001, Вы писали:
Кё>>Короче, в данном конкретном примере вообще никакого специального каста делать не нужно, компилятор сам смотрит тип аргумента функции (C*) и выполняет его. А dynamic_cast предназначен для выполнения _обратного_ преобразования, т.е. из С* получить A*. A>Я ведь вроде дал четкий пример A>Там два разных родительских класса B и C A>class A : public B,public C A>{ A>... A>}; A>Вопрос A>как вытащить адрес второго класса C
Ты плохо думаешь о компиляторе С++. Это не ассемблер и даже не Си. Взятие адреса &a не даёт тебе адрес в памяти начала этого объекта! Оно даёт тебе типизированный указатель. Если этот указатель используется в контексте C*, то он автоматически конвертируется (т.е. смещается).
A a;
A* pA = &a; // ok
B* pB = &a; // ok
C* pC = &a; // ok
Если преобразовать все указатели к void*, то получим (допустим):
pA == 0x500000
pB == 0x500000
pC == 0x500010
Основная идея наследования — любой объект класса A является объектом класса B и объектом класса C. Везде, где используются типы B или C, можно подставить их наследников.
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, Andrew001, Вы писали:
A>>Как из класса A вытащить адрес класса C? A>>A a; A>>d(?????????????????);
Кё>Вот так: Кё>
Кё>d(&a);
Кё>
Кё>Конвертируется автоматически. Если есть неоднозначночть, компилятор будет ругаться.
А если будет ругаться то что делать в этом случае?
И еще.
Класс C хоть и родительский но он стоит после класса B
И даже если компилятор не пошлет то фактически в качестве параметра я получу адрес класса B
Согласись это не совсем то что требуется
Здравствуйте, CyberZX, Вы писали:
CZX>Здравствуйте, Andrew001, Вы писали:
A>>Здравствуйте, Аноним, Вы писали:
А>>>Здравствуйте, Andrew001, Вы писали:
А>>>Вот так:
А>>>
А>>>d(static_cast<C*>(&a));
А>>>
A>>Большое спасибо A>>И еще один вопрос на эту тему A>>Как решить эту же задачу но если процедура d член класса A A>>class A : public B,public C A>>{ A>>... A>> void d(); A>>};
A>>void A::d() A>>{ A>> ????????; A>>} A>>Требуется найти адрес класса C находясь в теле процедуры d CZX>static_cast<C*>(this);
Но это ведь самое обычное преобразование типов
Разве не проще написать вот так:
(C*)this;
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Andrew001, Вы писали:
А>Вот так:
А>
А>d(static_cast<C*>(&a));
А>
Большое спасибо
И еще один вопрос на эту тему
Как решить эту же задачу но если процедура d член класса A
class A : public B,public C
{
...
void d();
};
void A::d()
{
????????;
}
Требуется найти адрес класса C находясь в теле процедуры d
Здравствуйте, Andrew001, Вы писали:
Кё>>Конвертируется автоматически. Если есть неоднозначночть, компилятор будет ругаться. A>А если будет ругаться то что делать в этом случае?
показать сообщение об ошибке, и снова спросить "что делать".
A>И еще. A>Класс C хоть и родительский но он стоит после класса B A>И даже если компилятор не пошлет то фактически в качестве параметра я получу адрес класса B A>Согласись это не совсем то что требуется
Нет, компилятор не настолько глуп. Он вполне способен правильно выполнить преобразование, и вычислить указатель на подобъект С.
Здравствуйте, Andrew001, Вы писали:
A>Здравствуйте, Аноним, Вы писали: A>Большое спасибо A>И еще один вопрос на эту тему A>Как решить эту же задачу но если процедура d член класса A A>class A : public B,public C A>{ A>... A> void d(); A>};
A>void A::d() A>{ A> ????????; A>} A>Требуется найти адрес класса C находясь в теле процедуры d
что такое адрес класса и зачем тебе это нужно, если к переменным и методам класса C и так можно обратиться из A::d()
Здравствуйте, Andrew001, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, Andrew001, Вы писали:
А>>Вот так:
А>>
А>>d(static_cast<C*>(&a));
А>>
A>Большое спасибо A>И еще один вопрос на эту тему A>Как решить эту же задачу но если процедура d член класса A A>class A : public B,public C A>{ A>... A> void d(); A>};
A>void A::d() A>{ A> ????????; A>} A>Требуется найти адрес класса C находясь в теле процедуры d
static_cast<C*>(this);
Здравствуйте, sadomovalex, Вы писали:
S>Здравствуйте, Andrew001, Вы писали:
A>>Здравствуйте, Аноним, Вы писали: A>>Большое спасибо A>>И еще один вопрос на эту тему A>>Как решить эту же задачу но если процедура d член класса A A>>class A : public B,public C A>>{ A>>... A>> void d(); A>>};
A>>void A::d() A>>{ A>> ????????; A>>} A>>Требуется найти адрес класса C находясь в теле процедуры d
S>что такое адрес класса и зачем тебе это нужно, если к переменным и методам класса C и так можно обратиться из A::d()
Ты лучше скажи как это сделать а я потом постараюсь объяснить зачем мне это нужно
ОК?
Здравствуйте, Andrew001, Вы писали:
A>Ты лучше скажи как это сделать а я потом постараюсь объяснить зачем мне это нужно A>ОК?
Нет, ты сначала говоришь, что хочешь получить, а затем тебе скажут, как это лучше сделать. Иначе окажешься в положении прапорщика "да что тут думать, прыгать надо!"
Здравствуйте, Слоноежик, Вы писали:
С>Правильный способ.
С>
С>dynamic_cast<C*>(&a);
С>
С> А если есть виртуальные функции то единственный. Поправьте если ошибаюсь.
А если я напишу (C*)&a это разве не тоже самое преобразование типов?
если нет то подскажите разницу
Здравствуйте, Andrew001, Вы писали:
A>А если я напишу (C*)&a это разве не тоже самое преобразование типов?
В общем случае — нет. A>если нет то подскажите разницу
Посмотри этот топик
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, Слоноежик, Вы писали:
С>>Правильный способ.
С>>dynamic_cast<C*>(&a);
С>> А если есть виртуальные функции то единственный. Поправьте если ошибаюсь.
Кё>А если RTTI отключен и виртуальных функций нет, то неправильный
Кё>Возможны два варианта:
Кё>1. `A` содержит один экземпляр класса `C`, неважно, путём виртуального наследования нескольких или обычным наследованием одного. Тогда static-cast или implicit-преобразование пройдут на ура. Кё>2. `A` содержит несколько экземпляров класса `C`. Тогда компилятор будет ругаться даже на dynamic_cast (из-за этого в рантайме dynamic_cast вернет ноль).
Кё>Короче, в данном конкретном примере вообще никакого специального каста делать не нужно, компилятор сам смотрит тип аргумента функции (C*) и выполняет его. А dynamic_cast предназначен для выполнения _обратного_ преобразования, т.е. из С* получить A*.
Я ведь вроде дал четкий пример
Там два разных родительских класса B и C
class A : public B,public C
{
...
};
Вопрос
как вытащить адрес второго класса C
Здравствуйте, Andrew001, Вы писали:
A>Я ведь вроде дал четкий пример A>Там два разных родительских класса B и C A>class A : public B,public C A>{ A>... A>}; A>Вопрос A>как вытащить адрес второго класса C
Тебе ведь уже дали вполне четкий ответ .
Повторюсь:
A a;
C* pC = &a;//Компилятор сам выполнит преобразование, и запишет в pC адрес подобъекта С объекта а.
C* pC2 = static_cast<C*>(&a);//То же самое, что и выше.
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, Andrew001, Вы писали:
A>>Ты лучше скажи как это сделать а я потом постараюсь объяснить зачем мне это нужно A>>ОК?
Кё>Нет, ты сначала говоришь, что хочешь получить, а затем тебе скажут, как это лучше сделать. Иначе окажешься в положении прапорщика "да что тут думать, прыгать надо!"
Ха
Может мне кинуть на сайт весь проект
У меня есть вопрос его и задаю
Помоему этого достаточно
Поправь меня если я не прав
Здравствуйте, Bell, Вы писали:
B>Здравствуйте, Andrew001, Вы писали:
A>>Я ведь вроде дал четкий пример A>>Там два разных родительских класса B и C A>>class A : public B,public C A>>{ A>>... A>>}; A>>Вопрос A>>как вытащить адрес второго класса C
B>Тебе ведь уже дали вполне четкий ответ . B>Повторюсь:
B>
B>A a;
B>C* pC = &a;//Компилятор сам выполнит преобразование, и запишет в pC адрес подобъекта С объекта а.
B>C* pC2 = static_cast<C*>(&a);//То же самое, что и выше.
B>
B>В конце концов напиши такой пример: B>
B>A a;
B>C* pC = &a;
B>B* pB = &a;
B>
B>и посмотри в отладчике значения pB и pC.
Наконецто))
Огромное спасибо за полный и развернутый ответ
Здравствуйте, Andrew001, Вы писали:
Кё>>Нет, ты сначала говоришь, что хочешь получить, а затем тебе скажут, как это лучше сделать. Иначе окажешься в положении прапорщика "да что тут думать, прыгать надо!" A>Ха A>Может мне кинуть на сайт весь проект A>У меня есть вопрос его и задаю A>Помоему этого достаточно A>Поправь меня если я не прав
Ты абстрагируешь свою проблему и излагаешь её. Потому что наилучший путь может оказаться совсем другим.
Re[5]: Доступ к родительским классам
От:
Аноним
Дата:
27.07.05 14:30
Оценка:
Здравствуйте, Andrew001, Вы писали:
A>Здравствуйте, CyberZX, Вы писали:
CZX>>Здравствуйте, Andrew001, Вы писали:
A>>>Здравствуйте, Аноним, Вы писали:
А>>>>Здравствуйте, Andrew001, Вы писали:
А>>>>Вот так:
А>>>>
А>>>>d(static_cast<C*>(&a));
А>>>>
A>>>Большое спасибо A>>>И еще один вопрос на эту тему A>>>Как решить эту же задачу но если процедура d член класса A A>>>class A : public B,public C A>>>{ A>>>... A>>> void d(); A>>>};
A>>>void A::d() A>>>{ A>>> ????????; A>>>} A>>>Требуется найти адрес класса C находясь в теле процедуры d CZX>>static_cast<C*>(this); A>Но это ведь самое обычное преобразование типов A>Разве не проще написать вот так: A>(C*)this;
ну вообще-то использывать С-style касты в С++ дурной тон. по многим, дотстаточно объективным причинам. используй лучше static_cast
Здравствуйте, Andrew001, Вы писали:
A>>>Требуется найти адрес класса C находясь в теле процедуры d CZX>>static_cast<C*>(this); A>Но это ведь самое обычное преобразование типов A>Разве не проще написать вот так: A>(C*)this;
Это — преобразование типа в стиле C (explicit type conversion, 5.4). Оно оставлено в C++ для обратной совместимости с C и выполняет одно из преобразований
const_cast<C*>(this), static_cast<C*>(this), const_cast<C*>(static_cast<const C*>(this)), reinterpret_cast<C*>(this) или const_cast<C*>(reinterpret_cast<const C*>(this)),
в зависимости от обстоятельств. В C++ считается хорошим тоном явно писать, какой из этих вариантов ты имеешь в виду.
Re[6]: Доступ к родительским классам
От:
Аноним
Дата:
27.07.05 14:41
Оценка:
Здравствуйте, Кодёнок, Вы писали:
Кё>Здравствуйте, Andrew001, Вы писали:
Кё>Основная идея наследования — любой объект класса A является объектом класса B и объектом класса C. Везде, где используются типы B или C, можно подставить их наследников.
ну это имеет место быть лишь при public наследовании
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, Andrew001, Вы писали:
CZX>>>static_cast<C*>(this); A>>Но это ведь самое обычное преобразование типов A>>Разве не проще написать вот так: A>>(C*)this; А>ну вообще-то использывать С-style касты в С++ дурной тон. по многим, дотстаточно объективным причинам. используй лучше static_cast
Еще можно boost::implicit_cast заюзать. Совсем хорошо будет.