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

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

14.05.2019, 11:44. Показов 8972. Ответов 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
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
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
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 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
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 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
18150 / 10732 / 2067
Регистрация: 27.09.2012
Сообщений: 27,047
Записей в блоге: 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
13229 / 6861 / 1827
Регистрация: 18.10.2014
Сообщений: 17,393
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
Ответ Создать тему
Новые блоги и статьи
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru