Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.57/30: Рейтинг темы: голосов - 30, средняя оценка - 4.57
0 / 0 / 0
Регистрация: 18.09.2018
Сообщений: 4

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

03.01.2020, 22:54. Показов 6965. Ответов 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
9005 / 4706 / 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
Ответ Создать тему
Новые блоги и статьи
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь(не выше 3-го порядка) постоянного тока с элементами R, L, C, k(ключ), U, E, J. Программа находит переходные токи и напряжения на элементах схемы классическим методом(1 и 2 з-ны. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru