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

Как заменить родителя на наследника?

20.03.2024, 13:17. Показов 1754. Ответов 22

Студворк — интернет-сервис помощи студентам
Здравствуйте, возможно ли как-то заменить родительский класс на его наследника?
У меня есть два класса:
C++
1
2
3
4
5
6
7
class Tile {
public:
friend ostream& operator <<(ostream& out, const Tile& t){
out<<' ';
return out;
}
};
C++
1
2
3
4
5
6
7
class Wall: public Tile {
public:
friend ostream& operator <<(ostream& out, const Wall& w){
out<<'#';
return out;
}
};
C++
1
2
3
4
Wall w;
Tile t;
t = w;
cout << t << w;// выводится пробел и #, а хотелось бы ##
Нужно это, чтобы в массиве можно было менять какие-то элементы на Wall, а какие-то обратно на Tile и т.д.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.03.2024, 13:17
Ответы с готовыми решениями:

Как избежать повтора параметров конструктора класса-родителя в конструкторе наследника?
С каждым новым наследуемом классом, число параметров конструктора увеличивается. class A { public: A(int a, float b, double c) ...

Доступ к приватному методу наследника через родителя
Тут натолкнулся на интересную штуку. #include &lt;iostream&gt; using namespace std; class A { public: virtual void f() { ...

Нужно из класса наследника передать параметры в класс родителя
#include &lt;stdio.h&gt; #include &lt;conio.h&gt; #include &lt;math.h&gt; class ploskost{ protected: float d; int x1,y1,x2,y2; public: ...

22
фрилансер
 Аватар для Алексей1153
6472 / 5691 / 1131
Регистрация: 11.10.2019
Сообщений: 15,168
20.03.2024, 13:28
Цитата Сообщение от daniiila Посмотреть сообщение
возможно ли как-то заменить родительский класс на его наследника
да запросто:

C++
1
2
3
4
Wall w;
Wall t;
t = w;
cout << t << w;
Добавлено через 1 минуту
хотя, тут, видимо, речь про динамический полиморфизм
0
0 / 0 / 0
Регистрация: 11.03.2024
Сообщений: 6
20.03.2024, 13:45  [ТС]
Как таким образом заменить элемент массива класса Tile на объект класса Wall?
0
фрилансер
 Аватар для Алексей1153
6472 / 5691 / 1131
Регистрация: 11.10.2019
Сообщений: 15,168
20.03.2024, 14:05
daniiila, так подойдёт?
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
#include <iostream>
#include <memory>
 
class Tile
{
    public:
    virtual std::ostream& operator <<(std::ostream& o)const
    {
        o<<'_';
        return o;
    }
    virtual ~Tile() = default;
};
 
class Wall: public Tile
{
    public:
    std::ostream& operator <<(std::ostream& o)const override
    {
        o<<'#';
        return o;
    }
};
 
std::ostream& operator <<(std::ostream& o, const Tile& t)
{
    t.operator<<(o);
    return o;
}
 
int main()
{
    std::unique_ptr<Tile> array[]{std::make_unique<Wall>(), std::make_unique<Tile>()};
    for(const auto& p:array){std::cout << *p;}
    std::cout << '\n';
    
    array[1]=std::make_unique<Wall>();
    for(const auto& p:array){std::cout << *p;}
    std::cout << '\n';
}
2
0 / 0 / 0
Регистрация: 11.03.2024
Сообщений: 6
20.03.2024, 14:41  [ТС]
Можете объяснить работу unique_ptr и make_unique?
Будет ли работать этот способ с моей перегрузкой операторов?
0
фрилансер
 Аватар для Алексей1153
6472 / 5691 / 1131
Регистрация: 11.10.2019
Сообщений: 15,168
20.03.2024, 15:29
daniiila, std::unique_ptr - умный указатель (сам умеет вызывать delete для хранимого указателя)

Цитата Сообщение от daniiila Посмотреть сообщение
Будет ли работать этот способ с моей перегрузкой операторов?
дружественную функцию виртуальной не сделать, поэтому у меня такой костыль
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
20.03.2024, 15:45
Цитата Сообщение от Алексей1153 Посмотреть сообщение
дружественную функцию виртуальной не сделать
Так и зачем ты выбрал дружественную функцию ???

Добавлено через 51 секунду
Да и я нигде не вижу friend
0
фрилансер
 Аватар для Алексей1153
6472 / 5691 / 1131
Регистрация: 11.10.2019
Сообщений: 15,168
20.03.2024, 16:11
SmallEvil, у меня её и нет
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,519
20.03.2024, 17:35
Цитата Сообщение от Алексей1153 Посмотреть сообщение
так подойдёт?
Код содержит UB.
1
фрилансер
 Аватар для Алексей1153
6472 / 5691 / 1131
Регистрация: 11.10.2019
Сообщений: 15,168
20.03.2024, 18:18
eva2326, да, забыл виртуальный деструктор
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
20.03.2024, 18:38
Цитата Сообщение от Алексей1153 Посмотреть сообщение
да, забыл виртуальный деструктор
зачем? "данному коду" деструктор не нужен.

Добавлено через 5 минут
Цитата Сообщение от Алексей1153 Посмотреть сообщение
std::unique_ptr<Tile> array[]{std::make_unique<Wall>(), std::make_unique<Tile>()};
тут не понятно почему в массиве с типом элементов std::unique_ptr<Tile> можно хранить элементы типа std::make_unique<Wall>, std::unique_ptr<Tile> и std::make_unique<Wall> разные типы.
0
фрилансер
 Аватар для Алексей1153
6472 / 5691 / 1131
Регистрация: 11.10.2019
Сообщений: 15,168
20.03.2024, 18:40
_stanislav, да, он тут не используется, но это всё равно считается UB, насколько я знаю

Цитата Сообщение от _stanislav Посмотреть сообщение
тут не понятно
потому что эти указатели умеют такое. И std::shared_ptr тоже так умеют (всё как у простых указателей )
1
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
20.03.2024, 18:41
Цитата Сообщение от Алексей1153 Посмотреть сообщение
забыл виртуальный деструктор
Это не приводит к НП (УБ)
0
фрилансер
 Аватар для Алексей1153
6472 / 5691 / 1131
Регистрация: 11.10.2019
Сообщений: 15,168
20.03.2024, 18:46
_stanislav, вот, даже в доке пример есть
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,519
20.03.2024, 21:15
Цитата Сообщение от _stanislav Посмотреть сообщение
зачем? "данному коду" деструктор не нужен.
Нужен.

Цитата Сообщение от SmallEvil Посмотреть сообщение
Это не приводит к НП (УБ)
Приводит.

https://en.cppreference.com/w/... ake_unique
https://en.cppreference.com/w/... unique_ptr
https://en.cppreference.com/w/... ult_delete
https://eel.is/c++draft/expr.delete#3
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13202 / 6837 / 1822
Регистрация: 18.10.2014
Сообщений: 17,294
21.03.2024, 01:48
Цитата Сообщение от daniiila Посмотреть сообщение
Как таким образом заменить элемент массива класса Tile на объект класса Wall?
Никак. Элементами массива Tile могут быть только Tile. Ничего заменить нельзя.

Цитата Сообщение от daniiila Посмотреть сообщение
C++
1
2
3
4
Wall w;
Tile t;
t = w;
cout << t << w;// выводится пробел и #, а хотелось бы ##
В коде ясно сказано, что объект t имеет тип Tile. Никакого другого типа этот объект никогда иметь не будет.
0
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
21.03.2024, 17:40
eva2326, не нашел, где написано что де
Цитата Сообщение от eva2326 Посмотреть сообщение
Нужен.

In a single-object delete expression, if the static type of the object to be deleted is not similar ([conv.qual]) to its dynamic type and the selected deallocation function (see below) is not a destroying operator delete, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. In an array delete expression, if the dynamic type of the object to be deleted is not similar to its static type, the behavior is undefined.

однако интересно почему отсутствие деструктора в базовом классе UB, вроде как должен вызваться деструктор статического типа напрямую, минуя таблицу виртуальных функций, нужно наверно исходники реализации посмотреть что бы понять где там возможно UB? лень конечно.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13202 / 6837 / 1822
Регистрация: 18.10.2014
Сообщений: 17,294
21.03.2024, 18:12
Цитата Сообщение от _stanislav Посмотреть сообщение
днако интересно почему отсутствие деструктора в базовом классе UB
Отсутствие виритуального деструктора в базовом классе...

Цитата Сообщение от _stanislav Посмотреть сообщение
вроде как должен вызваться деструктор статического типа напрямую, минуя таблицу виртуальных функций
В С++ нет понятия "таблица виртуальных функций".

Цитата Сообщение от _stanislav Посмотреть сообщение
нужно наверно исходники реализации посмотреть что бы понять где там возможно UB
Каким боком исходники какой-то "реализации" могут относиться к решениям из стандарта языка?

Однако стоит заметить, что в реальных реализациях на виртуальности деструктора держится не только вызов правильного деструктора как такового, но и вызов правильного operator delete с правильными аргументами. Стандарт писался с "подразумеванием" такого реализационного подхода

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cstdlib>
 
struct B {};
 
struct D : B
{
  void *operator new(std::size_t size)
    { return ::new char[size + 64] + 64; }
 
  void operator delete(void *ptr)
    { ::delete ((char *) ptr - 64); }
};
 
int main()
{
  D *d = new D;
  delete d; // ОК
  
  B *b = new D;
  delete b; // Падение
}
1
21.03.2024, 18:19

Не по теме:

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Каким боком исходники какой-то "реализации" могут относиться к решениям из стандарта языка?
вопрос риторический как я понимаю?

0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,519
21.03.2024, 18:52
Цитата Сообщение от _stanislav Посмотреть сообщение
не нашел, где написано что де
Вы внимательно прочли нормативный текст стандарта, и осознали что применение delete по отношению к наследнику через указатель на базовый класс, у которого отсутствует вирт. деструктор - это UB.
Но вам все равно не понятно, зачем в такой ситуации нужен вирт. деструктор?

Что бы не было UB, Карл!!!

Цитата Сообщение от _stanislav Посмотреть сообщение
вроде как должен вызваться деструктор статического типа напрямую
Обратите внимание на фрагмент цитаты:
Цитата Сообщение от _stanislav Посмотреть сообщение
if the static type of the object to be deleted is not similar to its dynamic type
Вот здесь всё хорошо:

C++
1
2
3
4
5
6
7
struct some {};
 
int main()
{
    some* p = new some;  // Динамический тип: some
    delete p;            // Статический тип: some
}
Однако если:
Цитата Сообщение от _stanislav Посмотреть сообщение
if the static type of the object to be deleted is not similar to its dynamic type
Где similar, это - такой же тип (без учета квалификаторов и тп. штук)

То стандарт накладывает дополнительное требование: что бы был вирт. деструктор.
Благодаря вирт. деструктору, компилятор может вычислить динамический тип удаляемого объекта.
Он использует это, например, для поддержки пользовательских операторов delete.
А так же, для того, что бы можно было запустить правильный деструктор наследника.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
21.03.2024, 18:52
Помогаю со студенческими работами здесь

Лишнее удаление родителя при создании класса наследника
Не могу понять откуда в выводе программы появляется первая надпись &quot;delete A&quot;. По идее надписей &quot;delete&quot; должно быть столько же,...

Правда, что указатель класса-наследника не может указывать на объект класса-родителя?
Доброго времени суток! Пример кода ниже. Правда ли , что указатель класса-наследника не может указывать на объект класса-родителя? ...

Сборка мусора у наследника и родителя
Добрый день. Есть класс родитель и класс наследник: public abstract class AbstractActivity extends AppCompatActivity { protected...

Доступ к private полю родителя из наследника
Здравствуйте! Изучаю Java, столкнулся с таким вопросом: Допустим, в родительском классе есть private-поле и private-метод. Вопрос: есть...

Вызывается метод родителя, а не наследника. (Проблема с наследованием в параметрах метода)
Помогите, пожалуйста, у меня есть класс Entity, в котором работает коллайдер. class Entity: public virtual void Visit(Bullet...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru