Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.63/35: Рейтинг темы: голосов - 35, средняя оценка - 4.63
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712

Вызов конструктора базового класса

14.05.2019, 11:44. Показов 8753. Ответов 73
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую всех. Создаю класс-наследник std::string. У базового класса есть конструктор копии: std::string(const std::string& str). Правильно ли я создаю конструктор копии для своего класса?
C++
1
2
3
4
5
class IString : public std::string
{
 public:
 IString(const IString& String) : std::string(String) {}
};
Такой код работает, но смущает то, что я в конструктор копии класса std::string передаю объект типа IString.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.05.2019, 11:44
Ответы с готовыми решениями:

Вызов конструктора базового класса
Здравствуйте! Я вот начал изучать C# и немножечко освежил ООП. Но вот у меня вопрос. Я точно помню, что класс-наследник (конструкторы не...

Вызов конструктора базового класса из порожденного
Есть Базовый класс студент: имеет поля: фамилия, адрес, тел., возраст. Порожденный класс группа: имя группы, кол-во студентов в...

Вызов конструктора базового класса из класса-наследника
Можно ли вне списка инициализации вызвать конструктор базового класса ? class A { int a; public: A(int c):a(c){} ...

73
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
15.05.2019, 11:59  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Похоже, он 17-й стандарт не поддерживает.
Он поддерживает 11.1, но как то ограниченно. В 11 стандарте есть функция std::to_string, но тут в системе нет такой функции.
0
19505 / 10108 / 2463
Регистрация: 30.01.2014
Сообщений: 17,828
15.05.2019, 13:38
d7d1cd, как минимум:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class IString : public std::string
{
public:
 IString() : std::string() {}
 IString(const char* src) : std::string(src) {}
 IString(std::string const & x) : std::string(x) {}
 
 IString & operator=(std::string const & x)
 {
     std::string::operator=(x);
     return *this;
 }
 IString & operator=(char const * x)
 {
     std::string::operator=(x);
     return *this;
 }
};
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
16.05.2019, 16:49
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Однако хрясь
так ты хер с яйцами не путай.

ты аллоцировал через маллок,
а удаляешь через операцию delete.

если ты аллоцируешь через маллок,
то и удаляй тогда через free, а не через delete.
и будет тебе счастье:

https://rextester.com/MGRM38026

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
#include <iostream>
 
struct A
{
  static void* operator new(std::size_t s)
  {
      std::cout << "A::malloc\n";
      return (char*) std::malloc(s + 100) + 100;
  }
    
  static void operator delete(void *p)
  {
      std::cout << "A::free\n";
      std::free((char*) p - 100);
  }    
    
  int a, b, c;
};
 
struct B : A
{
  static void* operator new(std::size_t s)
  {
      std::cout << "B::malloc\n";
      return (char*) std::malloc(s + 100) + 100;
  }
    
  static void operator delete(void *p)
  {
      std::cout << "B::free\n";
      std::free((char*) p - 100);
  }
};
 
int main()
{
  A *p = new B;
  delete p;
}
Code
1
2
B::malloc
A::free
Добавлено через 15 минут
Цитата Сообщение от Croessmah Посмотреть сообщение
Как это влияет на присутствие неопределенного поведения в коде?
Речь-то о том, что подобный код приводит к неопределенному поведению.
Код с UB может вполне нормально работать, однако UB как было, так и остается.
не с того места ты начинаешь.

тебе нужно ответить себе на вопрос:
почему у тебя в коде используется паттерн классического полиморфизма:
C++
1
2
3
auto* base = new der;
...
delete der;
но при этом вирт. деструктор ты почему то не хочешь?
религия что ли не позволяет?

на самом деле, если тебе не нужен вирт. деструктор,
значит тебе не нужен delete

если же тебе не нужен вирт. деструктор,
но нужен delete,
значит UB в коде - меньшая из твоих проблем.
0
261 / 111 / 53
Регистрация: 22.01.2017
Сообщений: 448
16.05.2019, 17:27
d7d1cd, кстати, рассмотрите правило 23 Майерса: Предпочитайте функциям-членам функции, не являющиеся ни членами, ни друзьями класса.
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
16.05.2019, 17:33
Цитата Сообщение от hoggy Посмотреть сообщение
ты аллоцировал через маллок,
а удаляешь через операцию delete.
Ты его посыл не понял.
Ты как всегда всё везде перепутал, перевернул с ног на голову,
и, смотрите, все дураки, один hoggy нормальный чувак.

Цитата Сообщение от hoggy Посмотреть сообщение
но при этом вирт. деструктор ты почему то не хочешь?
В каком месте я писал, что деструктор при этом не нужен виртуальный?

Ты как всегда всё везде перепутал, перевернул с ног на голову,
и, смотрите, все дураки, один hoggy нормальный чувак.

Нет смысла продолжать.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
16.05.2019, 17:43
Цитата Сообщение от Croessmah Посмотреть сообщение
все дураки, один hoggy нормальный чувак.
Не все. Я тоже считаю, что при неполиморфном наследовании инициализация указателя базового класса указателем на выделенную наследнику память - беда каждого кому хочется острых ощущений. И TheCalligrapher к общему (я надеюсь) облегчению, сказал нечто похожее, в последнем обращении к ТС. То что hoggy, выразился "от противного" и не слишком прозрачно, не делает сказанное не верным.
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
16.05.2019, 17:57
Цитата Сообщение от IGPIGP Посмотреть сообщение
Я тоже считаю
Ему как раз писали, что полиморфное удаление это ub и не хорошо.
Теперь же он считает, что он один писал, что это не нормально.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
16.05.2019, 18:05
Цитата Сообщение от Croessmah Посмотреть сообщение
Я вот вижу, что только hoggy писал о том,
что полиморфное удаление без виртуального деструктора - не беда,
хотя все ему писали, что это ub и не хорошо.
Теперь же он считает, что он один писал, что это не нормально.
А-а... Это про то, что "наследник не расширяет родителя нетривиально"? Тут стандарт не на его стороне, но по правде говоря нужно здорово изгалиться, чтобы найти тут приключения на собственную повседневность. Холиварноый вопрос.
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,038
Записей в блоге: 1
16.05.2019, 18:11
Цитата Сообщение от IGPIGP Посмотреть сообщение
Тут стандарт не на его стороне
Ему об этом уже писали не один раз.
Цитата Сообщение от IGPIGP Посмотреть сообщение
здорово изгалиться
TheCalligrapher продемонстрировал простой пример,
суть которого в том, что наследник просто захотел
использовать свой механизм распределения памяти.
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
16.05.2019, 18:26
Цитата Сообщение от Croessmah Посмотреть сообщение
TheCalligrapher продемонстрировал простой пример,
суть которого в том, что наследник просто захотел
использовать свой механизм распределения памяти.
Не спорю. Но можно запретить наследование, а самому придерживаться консистентной линии поведения на трезвую голову и внешней опоры, вроде стены или перил, в остальных случаях.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13211 / 6844 / 1824
Регистрация: 18.10.2014
Сообщений: 17,316
17.05.2019, 03:48
Цитата Сообщение от hoggy Посмотреть сообщение
так ты хер с яйцами не путай.

ты аллоцировал через маллок,
а удаляешь через операцию delete.
Опять бред полился густым потоком!

Гений ты наш, да, все правильно: я "аллоцировал через маллок, а удаляю через операцию delete"! Потому код и падает. Именно для демонстрации этого падения мой пример и составлен.

Суть тут в том, что возникает это несоответствие именно потому, что у класса нет виртуального деструктора. Именно из-за отсутствия виртуального деструктора происходит вызов неправильной перегрузки operator delete и программа падает.

Цитата Сообщение от hoggy Посмотреть сообщение
https://rextester.com/MGRM38026
Причем здесь этот пример - мне в упор не ясно. Вот показательный пример: http://coliru.stacked-crooked.... c6729ae214

Цитата Сообщение от IGPIGP Посмотреть сообщение
То что hoggy, выразился "от противного" и не слишком прозрачно, не делает сказанное не верным.
Из приведенного им примера сразу видно, чаш hoggy просто тупо не знает (несмотря на то, что ему это уже не раз объясняли), что перегруженный operator delete в классе на самом деле ведет себя как "виртуальная" функция (несмотря на то, что является static членом класса). И "виртуальность" функции operator delete в традиционной реализации держится целиком на виртуальности деструктора, т.е. реализуется через виртуальность деструктора.

http://eel.is/c++draft/class.free#4
11.11 Free store
4 [...] If the delete-expression is used to deallocate a class object whose static type has a virtual destructor, the deallocation function is the one selected at the point of definition of the dynamic type's virtual destructor. Otherwise, if the delete-expression is used to deallocate an object of class T or array thereof, the deallocation function's name is looked up in the scope of T. [...]
По этой причине легко построить пример класса, который падает из-за отсутствия виртуального деструктора, несмотря на то, что никаких новых подобъектов в производном классе нет. Что я и сделал.

Вызов неправильной версии operator delete является малоизвестным, но тем не менее реальным проявлением неопределенного поведения, вызванным попыткой полиморфного удаления при отсутствии виртуального деструктора.

---

Вот этот перл еще остался без должного внимания

Цитата Сообщение от hoggy Посмотреть сообщение
стандарт ясно даёт понять:
если нет виртуального деструктора,
то случится две вещи:
1.
деструктор наследника не будет запущен.
2.
за размер куска памяти, который нужно освободить, будет принят sizeof(object) удаляемого объекта.
Это целиком и полностью собственные выдумки вышепроцитированного автора. Ничего подобного в стандарте нет и никогда не было даже отдаленно.
3
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
17.05.2019, 09:56
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Из приведенного им примера сразу видно, чаш hoggy просто тупо не знает (несмотря на то, что ему это уже не раз объясняли), что перегруженный operator delete в классе на самом деле ведет себя как "виртуальная" функция (несмотря на то, что является static членом класса). И "виртуальность" функции operator delete в традиционной реализации держится целиком на виртуальности деструктора, т.е. реализуется через виртуальность деструктора.
Я тоже этого не знаю. И не совсем (или совсем не) понимаю. Если delete ведёт себя как виртуальный метод, то значит ли это, что если наследник не перегружает new/delete то он не унаследует данные реализации от предка? Имеется ввиду отсутствие виртуального деструктора но присутствие некоторого/рых виртуальных методов, то есть полиморфное наследование. Хотя раз уж столько сюрпризов, то хотелось бы знать и о не полиморфном случае, тоже, на всякий случай.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
21.05.2019, 23:29
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Суть тут в том, что возникает это несоответствие именно потому, что у класса нет виртуального деструктора
дык, это итак понятно.

мой цемес: не в том, что UB.

а в том: почему UB.

стандарт говорит: черт его знает, что там у вас с классами.
в общем случае - поведение не определенно.

я же предлагаю задуматься: почему так?

если рассмотреть не общий случай, а конкретный,
когда функции освобождения дают корректный адрес блока
(и размер, опционально)

тогда поведение становится определенным.


Добавлено через 1 минуту
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Это целиком и полностью собственные выдумки вышепроцитированного автора. Ничего подобного в стандарте нет и никогда не было даже отдаленно.

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

Добавлено через 3 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
В каком месте я писал, что деструктор при этом не нужен виртуальный?
Ты как всегда всё везде перепутал, перевернул с ног на голову,
и, смотрите, все дураки, один hoggy нормальный чувак.

что именно я перепутал?

ты вообще понял мой посыл?
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
22.05.2019, 00:14
стандарт говорит: разыменовывание нулевого указателя - есть UB
и вроде бы всё логично и понятно.

вот только стандарт так говорит, потому что это - его ответ на общий случай.
в общем случае никто не знает, чего там у вас, и как.

как насчет частного случая?

ты спросил меня:
Цитата Сообщение от Croessmah Посмотреть сообщение
Как это влияет на присутствие неопределенного поведения в коде?
вот теперь подумай как это влияет в конкретно-частном случае.

есть следующий код:

C++
1
2
3
4
5
6
7
8
9
struct sample
{
    static vod foo() {}
};
 
...
 
sample* p = nullptr;
p->foo();
вот теперь скажи мне, как это будет в конкретно этом случае.

мой цемес: в общем случае UB не значит, что в частном случае UB.
вроде бы просто и очевидно.

библиотека boost на этой простой истине построена.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
22.05.2019, 00:14

Знакомство с наследованием. Вызов конструктора базового класса
В инете немного почиатл про наследование и решил сразу перейти к практике Есть два класа point и apoint вот хидер #ifndef...

Вызов базового конструктора
Такая вот ситуация. Думаю, проблема в объявлении и инициализации массива m. Я бы инициализировал уже в конструкторе, но сначала вызовет...

Вызвать конструктор производного класса без конструктора базового класса
Здравствуйте! У меня есть базовый класс треугольник и производный класс равносторонний треугольник.В конструкторе треугольника вводятся...

Наследование конструктора из базового класса
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;cstring&gt; using namespace std; //////////////////// class String { ...

Инициализация конструктора базового класса
class animal { public: animal(int a):ianimal(a){} protected: int ianimal; }; class bird:public animal


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

Или воспользуйтесь поиском по форуму:
74
Ответ Создать тему
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru