0 / 0 / 0
Регистрация: 18.09.2018
Сообщений: 4

Восходящее преобразование массива производного класса к родительскому?

03.01.2020, 22:54. Показов 7035. Ответов 114

Студворк — интернет-сервис помощи студентам
Есть два класса base_Class(родитель) и derived_Class(потомок)
Есть некая виртуальная функция в base_Class которая принимает в качестве параметра массив объектов класса f(base_Class **mass)
Чтобы воспользоваться данной функцией для производного класса, необходимо привести массив производного класса к массиву родительского
Массивы: base_Class *baseMass[100], derived_Class *derivedMass[100]
Как произвести такое приведение типов?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.01.2020, 22:54
Ответы с готовыми решениями:

Определить обработчик исключений на преобразование указателя базового класса на указатель производного класса
Класс В является производным от класса А. Определить обработчик исключительной ситуации на преобразование указателя базового класса А на...

Восходящее преобразование
помогите пожайлуста разобраться, почему выдаёт ошибку... public class A{ public int f1(){return 1;}; public int...

Восходящее преобразование, объяснить код
Всем привет! Мне не понятен один момент в восходящем преобразовании. Есть два класса: один базовый, другой производный от базового. В...

114
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.01.2020, 23:06
Лучший ответ Сообщение было отмечено GoshaRubi как решение

Решение

Цитата Сообщение от GoshaRubi Посмотреть сообщение
Как произвести такое приведение типов?
https://rextester.com/EYVE25289

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <vector>
 
struct base
{
    virtual ~base(){}
    
    virtual void foo() { std::cout << "base::foo\n"; }
    int v = 33;
};
    
struct der: base
{
    virtual ~der(){}
    
    virtual void foo() { std::cout << "der::foo\n"; }
    int v[255];
};
 
    
void foo(base** arr)
{
    for(size_t i = 0; i != 3; ++i)
    {
        arr[i]->foo();
        delete arr[i];
    }
}
 
int main()
{
   
    der* arr[] = { new der(), new der(), new der() };
    foo( reinterpret_cast<base**>(arr) );
}
1
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
03.01.2020, 23:20
Цитата Сообщение от GoshaRubi Посмотреть сообщение
Как произвести такое приведение типов?
Никак.
hoggy, UB
1
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
03.01.2020, 23:26
Цитата Сообщение от rat0r Посмотреть сообщение
Никак.
Цитата Сообщение от GoshaRubi Посмотреть сообщение
Массивы: base_Class *baseMass[100], derived_Class *derivedMass[100]
а скопировать второй в первый?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.01.2020, 00:05
Цитата Сообщение от rat0r Посмотреть сообщение
hoggy, UB
пруф?
0
0 / 0 / 0
Регистрация: 18.09.2018
Сообщений: 4
04.01.2020, 00:24  [ТС]
hoggy спасибо
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
04.01.2020, 00:24
тож не пойму где UB, единственно для чуть большей безопасности изменить тип на base*const*
0
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
04.01.2020, 00:27
Цитата Сообщение от zayats80888 Посмотреть сообщение
а скопировать второй в первый?
Ну если это считать "приведением" массива одного типа к массиву другого, то тогда не никак. Но вроде так считать не принято.
Цитата Сообщение от hoggy Посмотреть сообщение
пруф?
https://timsong-cpp.github.io/... expr.add#6
1
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
04.01.2020, 00:35
rat0r,
In particular, a pointer to a base class cannot be used for pointer arithmetic when the array contains objects of a derived class type
Тут вроде написано про массив объектов, а не про массив указателей...
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.01.2020, 00:39
Цитата Сообщение от rat0r Посмотреть сообщение
https://timsong-cpp.github.io/cppwp/n4659/expr.add#6
ты ничего не перепутал?

не понятно, какое вообще отношение additive operators имеют к приведению типов?
1
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
04.01.2020, 00:44
Цитата Сообщение от zayats80888 Посмотреть сообщение
Тут вроде написано про массив объектов, а не про массив указателей...
После каникул спроси у учительницы по английскому что значит "In particular".
Цитата Сообщение от hoggy Посмотреть сообщение
ты ничего не перепутал?
Нет.
Цитата Сообщение от hoggy Посмотреть сообщение
не понятно, какое вообще отношение additive operators имеют к приведению типов?
У тебя в коде нет ничего кроме приведения типов?
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.01.2020, 00:58
Цитата Сообщение от rat0r Посмотреть сообщение
У тебя в коде нет ничего кроме приведения типов?
если есть что сообщить по существу - сообщай.
на нет и суда нет.
1
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
04.01.2020, 01:02
Цитата Сообщение от hoggy Посмотреть сообщение
если есть что сообщить по существу - сообщай
Да я уже вполне достаточно сообщил. Понять за тебя при чём тут https://timsong-cpp.github.io/... expr.add#6 и где оно выстреливает в твоём коде я не могу.
0
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
04.01.2020, 07:40
del
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.01.2020, 16:45
Цитата Сообщение от rat0r Посмотреть сообщение
Да я уже вполне достаточно сообщил.
ты ничего не сообщил по существу.
ты лишь скинул ссылку без каких либо объяснений.

любой дурак может сказать: в коде UB
не любой сможет объяснить: что конкретно с ним не так.

и если человек не может внятно объяснить что не так с кодом,
тогда зачем его вообще слушать?

Цитата Сообщение от rat0r Посмотреть сообщение
и где оно выстреливает в твоём коде я не могу.
в том то и дело, что в представленном коде нигде ничего не стреляет.

трудно показать черную кошку в черной комнате.
особенно, если её там нет.


я бы, конечно, мог бы обсудить с тобой,
почему ub`шные тезисы по твоей ссылке не подходят под данный случай.

но ты сам не желаешь ничего внятно объяснять,
и не даёшь развернутых ответов,

а я не хочу зря тратить своё время.
0
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
04.01.2020, 18:43
Цитата Сообщение от hoggy Посмотреть сообщение
ты ничего не сообщил по существу.
ты лишь скинул ссылку без каких либо объяснений.
любой дурак может сказать: в коде UB
не любой сможет объяснить: что конкретно с ним не так.
Я не ожидал, что в 2k20 в теме (в том числе) про массивы придётся разжёвывать при чём тут additive operators.
Цитата Сообщение от hoggy Посмотреть сообщение
и если человек не может внятно объяснить что не так с кодом,
тогда зачем его вообще слушать?
Посмотри на 25-ю (и/или 26-ю) строки в своём коде. Потом почитай https://timsong-cpp.github.io/... expr.sub#1. Надеюсь, после этого станет понятно, при чём тут additive operators. Потом можно вернуться к https://timsong-cpp.github.io/... expr.add#6, перейти оттуда к определению https://timsong-cpp.github.io/... ilar_types и подумать, являются ли типы base* (из выражения типа "pointer to [T = base*]", участвующего в арифметике указателей) и der* (array element type) similar.
Ответ
Не являются.

Цитата Сообщение от hoggy Посмотреть сообщение
я бы, конечно, мог бы обсудить с тобой,
почему ub`шные тезисы по твоей ссылке не подходят под данный случай.
но ты сам не желаешь ничего внятно объяснять,
и не даёшь развернутых ответов,
Ответ выше достаточно развёрнут?
2
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
04.01.2020, 21:54
GoshaRubi, вы пишете
Цитата Сообщение от GoshaRubi Посмотреть сообщение
Есть некая виртуальная функция в base_Class которая принимает в качестве параметра массив объектов класса f(base_Class **mass)
Квк указатель на указатель на базовый класс связан с массивом указателей вроде:
Цитата Сообщение от GoshaRubi Посмотреть сообщение
Массивы: base_Class *baseMass[100], derived_Class *derivedMass[100]
?
Покажите объявления метода и массивов в обоих классах.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.01.2020, 22:07
Цитата Сообщение от rat0r Посмотреть сообщение
Ответ выше достаточно развёрнут?
нет.
вообще не развернуто.

вместо того, что бы разъяснить какую конкретно ты видишь проблему в моём коде,
ты зачем-то начинаешь ссылаться на различные источники,
которые якобы должны пролить свет на неведомую проблему в коде.

ты саму проблему то обозначить можешь?
вот своими словами: что конкретно не так то?

нет. не сможешь.
потому что на самом деле в представленном мною коде нет никакой проблемы.
результат сборки - корректно работающая программа.


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

я тебя спрашиваю: почему нельзя то? что такого ужассного может случится?

и вместо того, что бы просто по-человечески объяснить банальную причину: "ну нас машина может задавить",
начинаешь нести какую то околесицу по принципу: "ну так в умной книжке написанно. вот там написанно - низзя".

и вот у меня возникает вопрос: ты вообще понимаешь почему "низзя" то?

вот ты сослался на:
Цитата Сообщение от rat0r Посмотреть сообщение
https://timsong-cpp.github.io/cppwp/n4659/expr.add#6
ты понимаешь о каком именно UB там написанно?
что именно может привести к некорректному поведению программы?

похоже что нет, не понимаешь.

а я тебе сейчас объясню на примерах,
который иллюстрируют UB в действии:

1.
UB, как следствие некорректной реинтерпритации масива данных
для типов с различным sizeof

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
 
struct base
{
    virtual ~base(){}
    
    virtual void foo() { std::cout << "base::foo\n"; }
    int v = 33;
};
    
struct der: base
{
    virtual ~der(){}
    
    virtual void foo() { std::cout << "der::foo\n"; }
    int v[255];
};
 
    
void foo(base* arr)
{
    for(size_t i = 0; i != 3; ++i)
        arr[i].foo();  // errror
}
 
int main()
{
    der d;
   
    der arr[] = { d, d, d };
    
    base* b = arr; // ok
 
    foo(b); // алгоритм будет думать, что ему передали массив base
    // хотя на самом деле это массв der, размер которых гораздо больше
    // в результате начало очередного объекта der будет вычисленно неверно
    // последствия - не определены. скорее всего - авария.
}
результат работы программы:
Code
1
Invalid memory reference (SIGSEGV)
2.
UB, как следствие реинтерпритации класса объекта,
без поправки на смещение адреса в условиях множественного наследования:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <vector>
 
struct base1
{
    virtual ~base1(){}
    
    virtual void foo() { std::cout << "base1::foo\n"; }
    int v = 33;
};
 
struct base2
{
    virtual ~base2(){}
    
    virtual void baz() { std::cout << "base2::baz\n"; }
    
    int v[255];
};
 
    
struct der: base2, base1
{
    virtual ~der(){}
    
    virtual void foo() { std::cout << "der::foo\n"; }
    int v[255];
};
 
    
void foo(base1** arr)
{
    for(size_t i = 0; i != 3; ++i)
    {
        arr[i]->foo();
        delete arr[i];
    }
}
 
int main()
{
   
    der* arr[] = { new der(), new der(), new der() };
 
    foo( reinterpret_cast<base1**>(arr) );  //ре-интерпритация
    // в отличие от легального преобразования типов
    // не делает поправку на смещение к подобъекту базового класса
 
    // алгоритм будет думать что по адресу находится base1,
    // хотя на самом деле там находится подобъект base2
}

результат работы программы:
Code
1
2
3
base2::baz
base2::baz
base2::baz
не крашнулась, но работает не правильно.



-------------------

итого:
проблема действительно может быть в случае неверной ре-интерпритации типа объекта.
однако, в представленном мною коде такой проблемы нет.
и отсюда у меня резонный вопрос: до чего конкретно ты докалебался?
1
285 / 176 / 21
Регистрация: 16.02.2018
Сообщений: 666
04.01.2020, 22:58
Цитата Сообщение от hoggy Посмотреть сообщение
вместо того, что бы разъяснить какую конкретно ты видишь проблему в моём коде,
ты зачем-то начинаешь ссылаться на различные источники,
которые якобы должны пролить свет на неведомую проблему в коде.
ты саму проблему то обозначить можешь?
Если до сих пор не понятно что UB из-за того, что для итерации по массиву из der* используется указатель на base* при том, что типы der* и base* не являются similar, то я не знаю, как это ещё объяснить.
Цитата Сообщение от hoggy Посмотреть сообщение
потому что на самом деле в представленном мною коде нет никакой проблемы.
результат сборки - корректно работающая программа.
Предсказуемо. Я почти на 100% был уверен, что всё в быстро придёт к "ВЫ ВСЁ ВРЁТИ!11 Нет сегфолта — нет UB!!1"
Поэтому особо тут не торопился распинываться с детальными доказательствами.
Цитата Сообщение от hoggy Посмотреть сообщение
вот ты заявляешь, что переходить на красный свет светофора нельзя.
Разве я это заявляю?
Цитата Сообщение от hoggy Посмотреть сообщение
вот ты сослался на:
Цитата Сообщение от rat0r Посмотреть сообщение
https://timsong-cpp.github.io/... expr.add#6
ты понимаешь о каком именно UB там написанно?
А какие UB бывают?
Цитата Сообщение от hoggy Посмотреть сообщение
что именно может привести к некорректному поведению программы?

Вроде ясно написано, что: «if the expressions P or Q have type “pointer to cv T”, where T and the array element type are not similar»

Цитата Сообщение от hoggy Посмотреть сообщение
не крашнулась, но работает не правильно.
Ты путаешь "ожидаемо" с "корректно"/"правильно".

Добавлено через 13 минут
Цитата Сообщение от hoggy Посмотреть сообщение
C++
1
2
foo( reinterpret_cast<base1**>(arr) ); //ре-интерпритация
 // в отличие от легального преобразования типов
?????
Чем "ре-интерпретация" не легальна?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.01.2020, 23:37
Цитата Сообщение от rat0r Посмотреть сообщение
А какие UB бывают?
разные бывают.
смысл не в том: "какие".
смысл в том: "почему".

Цитата Сообщение от rat0r Посмотреть сообщение
Ты путаешь "ожидаемо" с "корректно"/"правильно".
нет, не путаю.

UB - неопределенное поведение.
в данном случае поведение - определенное.

и корректное, поскольку приводит к нужному результату именно так,
как оно изначально и задумывалось.

Цитата Сообщение от rat0r Посмотреть сообщение
Если до сих пор не понятно что UB из-за того, что для итерации по массиву из der* используется указатель на base* при том, что типы der* и base* не являются similar, то я не знаю, как это ещё объяснить.
о каком таком неопределенным поведении ты толкуешь,
учитывая, что в данной ситуации поведение совершенно точно определенно,
и полностью совпадает с ожидаемым?

Цитата Сообщение от rat0r Посмотреть сообщение
Разве я это заявляю?
конечно.
ты не заметил что обозначил ситуацию как UB,
невзирая на то, что поведение полностью определенно?

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

на красный свет нельзя идти потому, что можно попасть в аварию?
или просто потому что так написанно в книге?

Цитата Сообщение от rat0r Посмотреть сообщение
Чем "ре-интерпретация" не легальна?
задай этот вопрос тому, кто такое утверждает.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.01.2020, 23:37
Помогаю со студенческими работами здесь

Передача массива в конструктор производного класса
Народ, задача такая: Создать абстрактный класс с виртуальной функцией – норма. Создать производные классы : комплексные ...

Восходящее и нисходящее преобразование (Upcasting and Downcasting)
Посоветуйте литературу по данному вопросу в разрезе С++ ну или простыми словами что это, для чего нужно заранее спасибо

Неявное восходящее преобразование при защищенном/закрытом наследовании
Здравствуйте. Читаю книгу Стивена Прата по C++. Попался непонятный момент: в одной таблице (в таблице 14.1 в 6-й рус. редакции на стр....

Как сложить объект базового класса с объектом производного(наследуемого класса)
Как умножить объект базового класса с объектом производного(наследуемого класса): ozenka - объект базового класса, а ves- производного ...

Почему объект производного класса не видит префиксный оператор из базового класса?
Короче создал я базовый класс с перегруженным префиксным оператором ++. Потом чтоб его затюнинговать, сделал ему производный класс с...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

Новые блоги и статьи
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru