LINUX.ORG.RU

C++ непонимание наследования классов

 


0

4

Здравствуйте, коллеги!

class Parent{
private:
  int i;
public:
  Parent& operator = (Parent &p){
    this->i = p.i;
  }
};

class Child: public Parent{

};

Мне нужно сделать конструкцию типа:

Parent p;
Child c;
c = p;

Т.е. что бы, по большому счету сработал перегруженный оператор «=» из родительского класса. Произошла инициализация "i"б находящийся в protected базового класса. Но я не понимаю как это сделать.



Последнее исправление: HighMan (всего исправлений: 2)
Ответ на: комментарий от soomrack

Почему?

Мне действительно сложно добавить что-то к уже сказанному.

Я хочу записать полученное значение в переменную

Не вопрос.

и так, чтобы эта переменная не менялась в коде.

Вот. Это важно. Но это - не default ни в одном глазу. Обычно если хочется capture something by-val Вы захотите иметь макс свободу действий. Почему условный «holder» должен быть const - за пределами моего рационального восприятия. И мы же сейчас про темплейты говорим (когда конкретный тип не известен), правда?

Можно написать и «const int»

Конкретно с ints разницы не будет.

bugfixer ★★★★★
()
Ответ на: комментарий от soomrack

Вообще применение или нет, лямбд, это плохой пример.

Вы тут часто упоминаете Python, так вот есть замечательная книга. (Пишу по памяти, так как давно читал.)" Чистый Питон, программирование для профи." Мне эта книга понравилась так как показывает что и когда лучше делать а что нет. Да еще приятно когда разделяешь с автором его точку зрения.

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

P.S. Я вообще задумался, интересно а лямбда все таки относится к ОО или нет.

mx__ ★★★★★
()
Ответ на: комментарий от bugfixer

Нет, в этом примере свой template мне не нужен. Const мне удобен, но мне гораздо важнее, что этот код выглядит как одна команда.

Можно ли писать без лямбд? Конечно.

Можно ли писать понятный, защищенный код без лямбд? Конечно.

Необходимо ли использовать лямбды в современном программировании на С++ (чтобы под этим не подразумевалось). Нет, конечно.

Это просто еще один из инструментов, который позволяет облегчить написание и отладку кода. И как любой инструмент, его эффективность очень субъективна.

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

soomrack ★★★★★
()
Ответ на: комментарий от mx__

Как она в оригинале звучит?

Лямба к концепции ООП не относится, она относится к концепции функционального программирования.

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

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

soomrack ★★★★★
()
Ответ на: комментарий от soomrack

Const мне удобен, но мне гораздо важнее, что этот код выглядит как одна команда.

Я мог бы довольно долго рассуждать на тему опасностей которые таит в себе кажущаяся простота (Вы хотя бы примерно представляете в какой asm эта конструкция развернётся?), но сейчас меня интересует другое. Чуть раньше мы разговаривали об изменениях в программировании за последние 30 лет. Так вот, в контексте плюсов C++11 был революцией - подходы изменились фундаментально (я, кстати, удивлён что это не попало в Ваш список). В частности благодаря введению rvalue-refs and move semantic. И если раньше у const практически не было downsides, то теперь они есть и довольно серьёзные (в частности из такой переменной нельзя делать move). Я просто хочу убедиться что Вы отдаёте себе в этом отчёт, вот и всё.

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

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

Мой скачек, про осознание плохого кода был в период, когда я много писан на перле, он был мой основной язык в тот период жизни, я был тогда классическим вебмастером (сайты, схемы, монетизация, трафик, серваки, боты и пр.пр.пр.).

Касательно С++ мой переход был от времен до стандарта, т.е. до С++98 к С++17. Грубо говоря, я почти не использовал шаблоны и писал код в стиле 80х. Потому что так было в книгах про алгоритмы, потому что никто не рассказывал, очень много «почему». Опять же, это сейчас книги доступны, а тогда что было у друзей или в билиотеке не на руках, то и читали, это в 00х появились CD киоски у каждого выхода с метро и развалы типа Юноны, модемный интернет по 5 руб за мегабайт и пр…

Поэтому, грубо говоря, мой скачек был вот с такого:

int s=0;
for(i=0;i<100;++i){ if(l[i]<6 && l[i]>2) ++s; }

вот примерно в это (продублировал, хотя это может не с с++17):

const auto success = std::count_if(values.begin(), values.end(), 
                            [](int val) { return val > 2 && val < 6; });

черт возьми, это было сложно написать, т.к. уже рефлекторно пишу иначе! Но тогда это было не просто приемлимым кодом, это было ОБЫЧНЫМ кодом, так писали почти все. Этот «стиль» был везде, т.к. так писали в книгах про алгоритмы, и пинали если пишут s++ а не ++s, т.к. оптимизация!

А самое страшное знаешь что? Что студенты, которые ко мне сегодня приходят, и которые что-то прогали, они пишут именно так! Потому что школьные учителя и учителя кружков в массе не изменились, они преподают так же, как тогда, как их научили по книгам 80х годов.

Что уж тут говорить про конструкторы переноса и пр…

PS: а что про const говорить? это ключевое слово для компилятора и только для него. Это не константа в физическом смысле, я даже студентам, которые посмышленее даю задание изменить const так, чтобы компилятор не ругался, это улучшает понимание, что это есть такое…

PPS:

Вы хотя бы примерно представляете в какой asm эта конструкция развернётся?

с -02 – понятия не имею. Это не для оптимизации, это для большей прозрачности кода и скорости написания кода. Если нужно детально понимать что будет происходить, то я буду использовать другие конструкции. Этот стиль кода, он больше для использования С++ для сложных ПОИСКОВЫХ задач, для которых сейчас используют питон (я стараюсь в этих задачах тоже перейти на С++, т.к. для сложных задач, где нужна точность и понимание что и как происходит с данными, питон мне не подходит, я ни черта не понимаю, что у него под капотом, какие-то обертки, абстракции, странные названия для простых поведений… тут я бы вылил много говна на него, а точнее на программистов, которые его используют для задач, к которым он не предназначен, но это предмет другой дискуссии, и кажется, я ее однажды тут уже вел).

soomrack ★★★★★
()
Последнее исправление: soomrack (всего исправлений: 4)
Ответ на: комментарий от mx__

С++ это мультипарадигмый язык. Страуструп говорил, то одно из принципиальных целей языка это было оставить простое – простым, и сохранить скорость си для железа.

С++ это уже очень давно не С с классами, собственно, он никогда так и не позиционировался.

В целом выделяют три концепции:

  1. процедурное программирование, которое фактически запретило перекрестные циклы, и весь код развалился на отдельные функции, состоящие из четких loop… Помнится, когда я угорал по ассемблеру, я в какой-то момент написал функцию на три экрана, которая рисовала какую-то сложную фигуру, там было три или четыре пересекающихся цикла… Я ее написал, запустил, она отработала все все случаи как надо, я понял, что постиг дзен и больше на асме не писал.

  2. ООП, которое запрещает свободную интерпретацию типов переменных (прощай гибкость языка си!), т.е. ООП это очень жесткий контроль за типами, а не инкапсюляция, наследование, полиморфизм – это все добавки, помогающие с «сокрытием сложности» и «организации данных».

  3. функциональное программирование, оно запрещает менять значения переменных, т.е. переменных больше нет, теперь все константы. Это самая старая концепция, она появилась до процедурного (примет, Дейкстра) и до ООП… Она имеет самую хорошую теоретическую базу, но, соответственно, самую плохую практическую применимость…

С++, как и ряд других языков, это мультипарадигмый язык, он позволяет писать код в любой парадигме или в сочетании их.

В целом, все эти вещи, парадигмы, конвенции, бла-бла-бла, они нужны для одной простой вещи: как писать в 10 раз больше кода (по выполняемым зачам), совершая то же количество ошибок. Ну и конечно, тут все сильно индивидуально, у кого-то лучше получается код в одной концепции, у кого-то в другой, кто-то лучше пишет используя одни инструменты языка, кто-то другие…

В целом эволюция С++ среди всех серьезных языков самая лучшая, имхо, отличная обратная совместимость, просто отличная (copmare to python 2 -> 3), но эволюция медленная… Я бы предпочел, чтобы они меньше сосредотачивались на абстрактном программировании (constraints и т.п.) и больше на развитии стандартных библиотек (utf8, матрицы и пр)… Но все равно, для меня они этакий эталон среди альтернатив…

soomrack ★★★★★
()
Ответ на: комментарий от soomrack

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

С традициями LORа я знаком ;) Не переживайте - меня это абс «не парит». Как Вам удобнее ;) Я просто привык «по другому» так как никогда не знаешь кто по ту сторону экрана ;)

вот примерно в это (продублировал, хотя это может не с c++17)

Можно позанудствовать? По хорошему нужно дёргать begin(Cont) и end(Cont) дабы покрыть массивы.

Этот «стиль» был везде

На самом деле, ничего криминального в таких for-лупчиках нет, и зачастую это остаётся самым быстрым способом итерации (если сомневаетесь - посмотрите на disasm, я это делаю регулярно - очень познавательно).

Что студенты, которые ко мне сегодня приходят

В силу многих причин я очень трепетно отношусь к людям которые занимаются преподаванием. Правда. На самом деле - если бы я не знал чем Вы занимаетесь я бы даже не влезал, и не пытался донести / отстоять свою точку зрения. А так - глядишь и butterfly effect случится ;)

bugfixer ★★★★★
()
Ответ на: комментарий от mx__

http://library.lol/main/92A4E961E52194DA5C1A637E80FCF8B9

Python Tricks

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

В целом хорошая книга, я бы ее рекомендовал начинающим программистам на питоне. Про русский перевод не скажу – не смотрел.

В целом я не могу порекомендовать какой-то прям очень хорошей книги по питону, потому что он никогда не являлся моим основным языком, хотя последние несколько лет я его использовал довольно активно… но для своих специфичных задач, типа связки ipython + selenium (щас это называется иначе)…

Mastering Python 2016 года была неплохая книга… Но это скриптовый язык, соответственно, нужно читать best practice для конкретной своей области — ML, Django,…

soomrack ★★★★★
()
Ответ на: комментарий от bugfixer

Я очень открыт к новому, потому что я не считаю себя проф. программистом (хотя, тут формально есть разные критерии, если судить по количеству интернет трафа, людей, которое прошло через мой код, то я в топ 10% точно попаду… в некоторые года), но это решение конкретных сиюминутных практических задач, а не фундаментальный код… Разница, конечно, чудовищна между этими областями…

И объективно говоря, я очень плохо знаю С++, но меня спасает то, что я обычно стараюсь понять до той степени, в которой это необходимо для решения задачи.

На самом деле, ничего криминального в таких for-лупчиках нет, и зачастую это остаётся самым быстрым способом итерации (если сомневаетесь - посмотрите на disasm, я это делаю регулярно - очень познавательно).

И да, и нет. Касательно этого примера – for с массивом вполне приемлим для ряда задач, особенно когда нужно быстродействие, но тут есть нюансы, которые сегодня недопустимо уже делать:

int s=0;
for(i=0;i<100;++i){ if(l[i]<6 && l[i]>2) ++s; }
  1. форматирование, оно отстутсвует

  2. именование переменных – просто дно, i если и можно употреблять, то только для мнимой единицы, l – нельзя. Однажды я три дня отлаживал программу в которой в одном месте вместо l было написано 1.

  3. magic constants

А если говорить про обработку данных, когда нет жесткого требования по быстродействию, то код

const auto success = std::count_if(values.begin(), values.end(), 
                            [](int val) { return val > 2 && val < 6; });

или с «range» выглядит гораздо понятней (2 и 6 тоже закинуть в переменные с нормальным названием). И гораздо гибче, нет жесткой привязки к типам, это обычное высокоуровневое абстрактное программироание, когда код отражает то, что хочется получить без привязки к типу данных и магическим константам…, с контролем выхода за границы массивов и пр.

По поводу быстродействия ООП… Был у меня опыт по потреблению памяти и скорости, в 2-3 раза было лучше сделать на структурах в c-style… рекламный движок делали… с ооп в те времена в оперативу не влезли :)

soomrack ★★★★★
()
Последнее исправление: soomrack (всего исправлений: 1)
Ответ на: комментарий от soomrack

И объективно говоря, я очень плохо знаю С++

Любой кто Вам заявит иначе - лжец. По долгу службы мне приходилось общаться с сотнями и тысячами разработчиков. Из них действительно талантливых - единицы. И единицы способны обсуждать нюансы плюсов в терминах «буквы закона» и стандартов. ПыСы: к ним я себя не отношу.

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

А вот это - самый правильный подход. Никого не интересуют теоретические разглагольствования, хотят «условного» выхлопа. Жаль что так немного людей это осознаёт.

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

Я говорю про c.begin() vs begin(c). Второе работает для plain old C-arrays тоже.

А, увидел :). Но прямо сейчас мне кажется, что container.begin() лучше, т.к. этот код подразумевает, что container есть и в нем есть свои функции, реализованные в соотв. со спецификой контейнера… А для old-style имхо лучше использовать old-style, сюрпризов меньше – или я пишу код в старом стиле или в новом, смешения я стараюсь не допускать…

soomrack ★★★★★
()
Ответ на: комментарий от bugfixer

А вот это - самый правильный подход. Никого не интересуют теоретические разглагольствования, хотят «условного» выхлопа. Жаль что так немного людей это осознаёт.

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

soomrack ★★★★★
()
Ответ на: комментарий от bugfixer

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

Сейчас подкину дровишек в топку - и никто, подчёркиваю - никто, из этих наиболее талантливых VS Code (или любую другую IDE) не использует. Делайте выводы, господа…

bugfixer ★★★★★
()
Ответ на: комментарий от bugfixer

Тут мне сложно судить. Я emacs использую со своими конфигами уже много-много лет. Почему не vim? Наверное, потому, что первый текст-процессор был для меня был емакс… Других причин я не вижу.

Про VS Code много слышал, и судя по всему, для начального уровня она очень неплоха. Раньше я советовал CLion, т.к. она позволяла быстро начать писать код, для виндузятников я советовал и советую Visual Studio, т.к. а на чем еще писать если вы разрабатываете код под винду? А для серверной или фундаментальной разработки – в перспективе всем советовал смотреть на vim или emacs, больше на emacs, т.к. в этом случае я смог бы ответить на вопросы…

soomrack ★★★★★
()
Ответ на: комментарий от mrjaggers

Да ладно, насколько я знаю только в с/с++ это выделено в имена что на них ругается компилятор (из-за извращений с указателями), вроде в других языках про это не особо задумываются. (про Rust я хз)

mx__ ★★★★★
()
Ответ на: комментарий от Ivan_qrt

до того, как разобрался во всяких lvalue, rvalue и временах жизни.

эммм… но это базовые понятия ЯПов вообще. Пока не постигнешь такого, далеко не напишешь.

Вы реально думаете что Вы полностью понимаете value categories? Снимаю шляпу.

bugfixer ★★★★★
()
Ответ на: комментарий от mx__

Ещё.

Классы весьма редко нужны.
struct === объект.
Объекты бывают разной архитектуры.
Class - всего лишь один из способов работы с объектами.

У меня так.

Разработано API для использования метаданных.
Позволяет в run-time создать объект любой сложности и работать с ним.

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 2)
Ответ на: комментарий от Forum0888

Классы весьма редко нужны. struct === объект. Объекты бывают разной архитектуры. Class - всего лишь один из способов работы с объектами.

Оуеть. Так и запишем - нах инкапсуляцию. Да.

bugfixer ★★★★★
()
Ответ на: комментарий от mx__

Кстати многие популярные проекты с использованием struct реализуют а-ля интерфейсы (SDL, ...).

Многие «нахватались» терминов с class и уверены, что «по другому никак».
С ними трудно вести диалог, потому что они «знают».

В API, использующем метаданные много чего поддержано: свойства (любой сложности) полей и объектов, рефлексия, «динамичность», ...

Сказал о своём API лишь для того, чтобы ещё раз акцентировать то, что class является лишь одним из способов работы с объектами и ИМХО «так себе».
Class практически не использую.

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 5)
Ответ на: комментарий от Forum0888

Это большая тема, но с вами диалога не будет.

Безусловно. Потому как вы вес своего мнения только что обнулили. Я думаю - это моя последняя реплика в ваш адрес. Удачи в поиске лопоухих!

bugfixer ★★★★★
()

HighMan суть моих постов была в том, чтобы акцентировать то, что class это всего лишь один из способов работы с объектами.

Не использую его из-за того, что у меня свой API для работы с объектами (ИМХО class всё же «не очень», но выбор конечно за вами).

Forum0888
()
Последнее исправление: Forum0888 (всего исправлений: 1)