Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
#1

Приведение к типу-наследнику - C++

30.03.2014, 20:52. Просмотров 1175. Ответов 22
Метки нет (Все метки)

C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
class A {
};
class B: public A {
    void foo() const { std::cout << "some is king of every fish"; }
};
int main() {
    A* pointer(new B);
    static_cast<B*>(static_cast<void*>(pointer))->foo();
    return 0;
}
Можите на пальцах объяснить, как, без каких бы то ни было проверок, без дополнительных вычислений на этапе выполнения вызвать метод foo класса B для объекта, указатель на который хранится, как указатель на А? Заранее спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.03.2014, 20:52     Приведение к типу-наследнику
Посмотрите здесь:

ООП. Динамическое приведение типа от родителя к наследнику - C++
Добрый день, коллеги. Проблема в следующем. Есть два библиотечных класса (xerces). 1) DOMElement class DOMElement : public DOMNode ...

Приведение к типу - C++
В чем разница? static_cast&lt;int&gt;(a); и (int)a

Приведение к базовому типу - C++
#include &lt;iostream&gt; using namespace std; class A{ public: virtual ~A() {} }; class B: public A{ };

Приведение переменной к другому типу - C++
float a = (float)x; // старый стиль float b = static_cast&lt;float&gt;(y); // современный стиль разве по старому не удобнее? почему...

Приведение void* указателя к типу - C++
struct tParamStruct { const char* Result; }; tParamStruct ParamStruct; void show(void *AdressPS) { // ????????

Приведение void* к типу указателя на структуру - C++
Тема обсуждалась здесь, но решения так и нет нормального Есть два (и более, хоть до 20) линейных списков и функция обхода списка В...

Приведение указателя на void к другому типу? - C++
в поиске смотрел - не помогло! Возникла проблемка: В книге сказано, что указателю на void можно присваивать все типы указателей без...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт CЭксперт С++
13052 / 7315 / 814
Регистрация: 27.09.2012
Сообщений: 18,052
Записей в блоге: 3
Завершенные тесты: 1
30.03.2014, 21:00     Приведение к типу-наследнику #2
виртуальную функцию?
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
30.03.2014, 21:39  [ТС]     Приведение к типу-наследнику #3
нет, в A о ней нет никакого упоминания. функция появляется только в B
DrOffset
7058 / 4199 / 949
Регистрация: 30.01.2014
Сообщений: 6,965
30.03.2014, 21:46     Приведение к типу-наследнику #4
Цитата Сообщение от CEBEP Посмотреть сообщение
нет, в A о ней нет никакого упоминания. функция появляется только в B
Это что, задание какое-то? То есть ответ должен быть в каких определенных рамках?
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
30.03.2014, 21:51  [ТС]     Приведение к типу-наследнику #5
нет, это проблема в реальном проекте... меня просто достало писать длиннющую конструкцию из статик-кастов, решил посоветоваться, как это сделать лучше. В правильности такой объектной архитектуры я уверен, с этой стороны пересматривать вопрос не хочу, так что просто хочется придумать более краткое, с точки зрения синтаксиса, решение
zss
Модератор
Эксперт С++
6321 / 5905 / 1913
Регистрация: 18.12.2011
Сообщений: 15,184
Завершенные тесты: 1
30.03.2014, 21:51     Приведение к типу-наследнику #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
class A {
};
class B:public A 
{
public:
    void foo() const { std::cout << "some is king of every fish"; }
};
int main() {
    A* pointer=new B;
    reinterpret_cast<B*>(pointer)->foo();
    return 0;
}
Но ответственность возлагается на программиста
DrOffset
7058 / 4199 / 949
Регистрация: 30.01.2014
Сообщений: 6,965
30.03.2014, 21:56     Приведение к типу-наследнику #7
Цитата Сообщение от CEBEP Посмотреть сообщение
нет, это проблема в реальном проекте...
Ну тогда напиши функцию, которая это будет делать и вызывай ее вместо кастов.
Кстати, зачем каст к void*? Лишний здесь он.

zss, reinterpret_cast тут вообще не подходит.
ValeryS
Модератор
6551 / 5017 / 463
Регистрация: 14.02.2011
Сообщений: 16,733
30.03.2014, 22:00     Приведение к типу-наследнику #8
Цитата Сообщение от CEBEP Посмотреть сообщение
меня просто достало писать длиннющую конструкцию из статик-кастов, решил посоветоваться, как это сделать лучше.
лучше не лучше но короче
сделай еще один указатель дочернего класса
примерно так
C++
1
2
3
 A* pointer(new B);
 B* pointerB=(B*)pointer;
pointerB->foo();
Добавлено через 2 минуты
А лучше,по моему,создавать сразу дочерний класс, а при необходимости приводить его к родительскому
zss
Модератор
Эксперт С++
6321 / 5905 / 1913
Регистрация: 18.12.2011
Сообщений: 15,184
Завершенные тесты: 1
30.03.2014, 22:01     Приведение к типу-наследнику #9
Цитата Сообщение от DrOffset Посмотреть сообщение
zss, reinterpret_cast тут вообще не подходит
Объясните. Компилятор обязан это проглотить!

Добавлено через 48 секунд
Цитата Сообщение от ValeryS Посмотреть сообщение
А лучше,по моему,создавать сразу дочерний класс, а при необходимости приводить его к родительскому
А автор что делает что-то другое?
ValeryS
Модератор
6551 / 5017 / 463
Регистрация: 14.02.2011
Сообщений: 16,733
30.03.2014, 22:04     Приведение к типу-наследнику #10
Цитата Сообщение от zss Посмотреть сообщение
А автор что делает что-то другое?
нет, создает то он наследника но тип то родителя
я имел ввиду
C++
1
 B* pointer =new B;
наследник то знает все про своего родителя и методы и члены
DrOffset
7058 / 4199 / 949
Регистрация: 30.01.2014
Сообщений: 6,965
30.03.2014, 22:04     Приведение к типу-наследнику #11
Цитата Сообщение от zss Посмотреть сообщение
Объясните. Компилятор обязан это проглотить!
Это здесь непричем. reinterpret_cast говорит, что указатель типа A, теперь будет считаться указателем типа B. То есть адрес не меняется, только тип указываемого. Однако в случае наследования в общем случае нет гарантий, что адрес наследника и адрес базы будут равны. Поэтому простая реинтерпретация адреса здесь не поможет и даже вредна, т.к. приводит к неопределенному поведению. static_cast тут уместен вполне, он проведет преобразование адреса, если оно необходимо.
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
30.03.2014, 22:09  [ТС]     Приведение к типу-наследнику #12
Цитата Сообщение от zss Посмотреть сообщение
Объясните. Компилятор обязан это проглотить!
требование - без дополнительных вычислений. В соответствии с тем, что я знаю, приведение в стиле си может порождать reinterpret_cast, который, как и dynamic_cast, разрешается только на этапе выполнения программы. В моём проекте обращение к этим данным происходит миллионы раз, подобное приведение может ощутимо сказаться на быстродействии.
DrOffset
7058 / 4199 / 949
Регистрация: 30.01.2014
Сообщений: 6,965
30.03.2014, 22:10     Приведение к типу-наследнику #13
Цитата Сообщение от CEBEP Посмотреть сообщение
порождать reinterpret_cast, который, как и dynamic_cast, разрешается только на этапе выполнения программы.
reinterpret_cast не разрешается на этапе выполнения. Но он здесь не подойдет по причинам, которые я описал в предыдущем посте.
zss
Модератор
Эксперт С++
6321 / 5905 / 1913
Регистрация: 18.12.2011
Сообщений: 15,184
Завершенные тесты: 1
30.03.2014, 22:11     Приведение к типу-наследнику #14
Цитата Сообщение от DrOffset Посмотреть сообщение
static_cast тут уместен вполне,
Вы абсолютно не правы.
Это как раз область ведения reinterpret_cast.
Т.е. мы выполняем действие, которое противоречит представлениям компилятора.
Он ведь не знает, что указатель показывает на экземпляр производного класса,
а мы знаем! Поэтому такое действие с точки зрения программиста оправдано.
http://ideone.com/tI2HnP
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.03.2014, 22:17     Приведение к типу-наследнику
Еще ссылки по теме:

Приведение двух классов к типу друг друга - C++
Всем добрый день, Прошу вашей помощи с пониманием принципов работы приведения типов. Проблема следующая: class Sterling1502...

Приведение void указателя к определенному типу с сохранением результата - C++
Есть функция funс(void *pointer, char type) { ... } Нужно чтобы в данной функции этот указатель приводился к определенному типу...

Приведение одного парметра-типа к другому разыменованному парметру-типу (указателю) в шаблонах - C++
Здравствуйте! изучаю C++, и есть такой вопрос, можно ли при инстанцировании, допустим, шаблонной функции привести один параметр-тип к...

Выражение должно относиться к целочисленному типу или типу перечисления без области видимости - C++
Добрый день,столкнулся с проблемой &quot;Выражение должно относиться к целочисленному типу или типу перечисления без области видимости&quot; в такой...

Выражение должно относиться к целочисленному типу или типу перечисления без области видимости - C++
#include &lt;iostream&gt; #include &lt;cmath&gt; using namespace std; int main() { int N; double Y = 0; setlocale(0,&quot;&quot;); cout &lt;&lt;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
CEBEP
105 / 105 / 9
Регистрация: 21.03.2010
Сообщений: 437
30.03.2014, 22:17  [ТС]     Приведение к типу-наследнику #15
Цитата Сообщение от ValeryS Посмотреть сообщение
А лучше,по моему,создавать сразу дочерний класс,
B является производным по отношению к A, как это показано в первом сообщении... или в виду имелось что-то другое?
Yandex
Объявления
30.03.2014, 22:17     Приведение к типу-наследнику
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru