Вопрос по ООП

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

anarch пишет:
И вообще рекомендуется использовать класс вместо структуру. Но вот оправдано ли использование вложенного класса вместо структуры?
Ну это дело вкуса. Что такое класс. Это структура с методами. Только добавлены открытые закрытые и защищенные методы и наследование. 
А теперь вопрос что делать с классами фабриками и классами изделиями. Пока были просто классы (станки ЧПУ) которые работали с int,float и т.д. (простые детали) это было понятно. Но когда начали производить автомобили и смартфоны (классы заготовки готовых изделий) то пришлось напрячься. Но производить индивидульно-заточенные станки ЧПУ дорого. Вот так и появилась высокое ООП, которое хрен кто понимает, но позволяет дилетантам дотачивать свои кустарные подделки. 

ПС: я просто сторонник  упрощенного ООП, так как памяти маловато, но проекты все же сложнее сруба или землянки.Ну хочется все же в доме иметь толчок и ванную.Да так что бы не наблюдать в помещении новоднение говен. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

qwone пишет:
Что такое класс. Это структура с методами. Только добавлены открытые закрытые и защищенные методы и наследование.
А что, в структурах всего этого не было?

anarch
Offline
Зарегистрирован: 10.09.2017

Все было кроме ООП...

qwone пишет:
Только добавлены открытые закрытые и защищенные методы и наследование. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

anarch пишет:

Все было кроме ООП...

qwone пишет:
Только добавлены открытые закрытые и защищенные методы и наследование. 

Т.е. в структурах С++ нету "открытые закрытые и защищенные методы и наследование"?

Вот же ж блин! А я не знал, и всю жизнь использовал :-( 

Век живи - век учись. Пойду напьюсь :(

b707
Offline
Зарегистрирован: 26.05.2017

qwone пишет:

ПС: я просто сторонник  упрощенного ООП, так как памяти маловато

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

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Пух, в С++ структура и классики - одно и то же. Почти. 

anarch
Offline
Зарегистрирован: 10.09.2017

ЕвгенийП пишет:
Век живи - век учись. Пойду напьюсь :(
Верное решение )

b707 пишет:
ну вроде уже несколько раз было показано, что грамотное использование классов в ардуине не увеличивает кода, а опять эта шарманка про нехватку памяти...
А где бы посмотреть в примерах правильное и не правильное использование?

А то при замене структуры на класс, флэша на 8 байт больше уходит.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

anarch пишет:
А где бы посмотреть в примерах правильное и не правильное использование?

А то при замене структуры на класс, флэша на 8 байт больше уходит.

А где бы посмотреть как это заменяют структуру на класс, что "флэша на 8 байт больше уходит"?

anarch
Offline
Зарегистрирован: 10.09.2017
​class TimerNode
  {
  public:
    uint32_t previous;
    uint32_t interval;
    Handler handler;
    TimerNode *pNext;

    TimerNode(uint32_t previous, uint32_t interval,
              Handler handler) : pNext(nullptr)
    {
      this->previous = previous;
      this->interval = interval;
      this->handler = handler;
    }
  };

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Если это ответ на мой вопрос, то нещитова. Вопрос был "как заменяют структуру на класс". Вот и покажите мне одинаковые  структуру и класс, чтобы они память по-разному жрали. Например, если в приведённом примере слово class заменить на слово srtuct - по-другому жрать будет?

anarch
Offline
Зарегистрирован: 10.09.2017

Что значит одинаковые? 

Я так думаю 8 Байт уходит на конструктор.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

anarch пишет:

Что значит одинаковые? 

Одинаковые - значит одинаковые. Вы не знаете смысла этого слова? Посмотрите в словаре.

anarch пишет:

Я так думаю 8 Байт уходит на конструктор.

Не, ну нормально так. А в структуре конструктора, что, не было? Ну, тогда, давайте ещё 100500 методов припишем и скажем, что не на 8, а на 800 байтов отличается.

Нет, Вы одинаковые попробуйте. Например прямо в этом примере замените class на struct и сравните.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП давайте лучше про Эру

anarch
Offline
Зарегистрирован: 10.09.2017

STRUCT:

struct string
{
  char *i;
};

void setup()
{
  Serial.begin(9600);
  string *str = new string{"Hello, World!"};
  Serial.println(str->i);
  delete str;
}
void loop() {}

/*
  Скетч использует 1488 байт (4%) памяти устройства. Всего доступно 32256 байт.
  Глобальные переменные используют 202 байт (9%) динамической памяти, оставляя 1846 байт для локальных переменных. Максимум: 2048 байт.
*/

CLASS:

class string
{
  public:
    char *i;
  string(const char *i)
  {
    this->i = i;
  }
};

void setup()
{
  Serial.begin(9600);
  string *str = new string("Hello, World!");
  Serial.println(str->i);
  delete str;
}
void loop() {}

/*
  Скетч использует 1488 байт (4%) памяти устройства. Всего доступно 32256 байт.
  Глобальные переменные используют 202 байт (9%) динамической памяти, оставляя 1846 байт для локальных переменных. Максимум: 2048 байт.
*/

Пошел искать 8 байт :(

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

anarch пишет:

Пошел искать 8 байт :(

Всё ЕвгенийП, не судьба Вам сегодня напиться )))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

anarch пишет:

STRUCT:

struct string
{
  char *i;
};

void setup()
{
  Serial.begin(9600);
  string *str = new string{"Hello, World!"};
  Serial.println(str->i);
  delete str;
}
void loop() {}

/*
  Скетч использует 1488 байт (4%) памяти устройства. Всего доступно 32256 байт.
  Глобальные переменные используют 202 байт (9%) динамической памяти, оставляя 1846 байт для локальных переменных. Максимум: 2048 байт.
*/

CLASS:

class string
{
  public:
    char *i;
  string(const char *i)
  {
    this->i = i;
  }
};

void setup()
{
  Serial.begin(9600);
  string *str = new string("Hello, World!");
  Serial.println(str->i);
  delete str;
}
void loop() {}

/*
  Скетч использует 1488 байт (4%) памяти устройства. Всего доступно 32256 байт.
  Глобальные переменные используют 202 байт (9%) динамической памяти, оставляя 1846 байт для локальных переменных. Максимум: 2048 байт.
*/

Пошел искать 8 байт :(

Ну, пример-то не корректный - они ж разные! Я Вас просил сделать их одинаковыми. Вот так, например

class string
{
  public:
    char *i;
  string(const char *i)
  {
    this->i = i;
  }
};

и

struct string
{
  public:
    char *i;
  string(const char *i)
  {
    this->i = i;
  }
};

Вот теперь искать надо.

anarch
Offline
Зарегистрирован: 10.09.2017

Ох... не знаю как Евгению а мне пришлось хряпнуть для храбрости, и приступить к изучению вопроса.

Взял в очередной раз в руки книжку и прочитал, что в С++ struct и class одно и то же.

Только модификаторы доступа по умолчанию разные struct - public, class - private.

А что использовать - это уже по вкусу.

Теперь все на своих полочках :) 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

anarch пишет:

Ох... не знаю как Евгению а мне пришлось хряпнуть для храбрости, и приступить к изучению вопроса.

Взял в очередной раз в руки книжку и прочитал, что в С++ struct и class одно и то же.

Только модификаторы доступа по умолчанию разные struct - public, class - private.

А что использовать - это уже по вкусу.

Теперь все на своих полочках :) 

так Евгений Петрович применил методы нейролингвистического программирования, сказывается большой опыт общения со студентами )))

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

anarch пишет:

b707 пишет:
ну вроде уже несколько раз было показано, что грамотное использование классов в ардуине не увеличивает кода, а опять эта шарманка про нехватку памяти...
А где бы посмотреть в примерах правильное и не правильное использование?

Вообще-то, на форуме это обсасывалось 100500 раз, и «поиск» находится в правом верхнем углу. Но, по случаю пятницы, специально для своего собрата по ленивости задницы, так и быть, приведу ещё один пример.

Вот перемигивалка для красно-синего проблескового маячка (как у полиции). Мигает то красным, то синим, со стандартной для маячков частотой 80 раз в минуту (4/3 Гц).

static constexpr uint16_t NormF = 80;	// стандартная частота (миганий/мин)
static constexpr uint16_t LightInterval = 30000 / NormF; // полупериод в мс

static constexpr uint8_t pinRed = 9, pinBlue = 8; // пины маячков

void setup() {
	pinMode(pinRed, OUTPUT);
	pinMode(pinBlue, OUTPUT);
	digitalWrite(pinBlue, HIGH);	// синий изначально горит
}

void loop() {
	digitalWrite(pinRed, digitalRead(pinBlue));	// Красный копируем с синего
	digitalWrite(pinBlue, ! digitalRead(pinBlue)); // А синий инвертируем
	delay(LightInterval);
}
//
//Скетч использует 1046 байт (3%) памяти устройства. Всего доступно 32256 байт.
//Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт.
//

А вот она же, но создан класс «Светодиод» и вся работа с двумя светодиодами (красным и синим) идёт через переменные этого класса

//
//	Определяем классик для работы с пинами
// 	Пух, сорян, лямбд не подвезли :(
//
#define AI	__attribute__((always_inline))
template <uint8_t P>
struct TheLED {
	void set(const uint8_t v) const AI { digitalWrite(P, v); }
	inline uint8_t get(void) const AI { return digitalRead(P); }
	inline void setMode(const uint8_t v) const AI { pinMode(P, v); }
};	

//
//	Интервал и пины такие же, ничего не поменялось
//
static constexpr uint16_t NormF = 80;	// стандартная частота (миганий/мин)
static constexpr uint16_t LightInterval = 30000 / NormF; // полупериод в мс

static constexpr uint8_t pinRed = 9, pinBlue = 8;	// пины маячков

//
//	Переменные для пинов через наш класс
//
TheLED <pinRed> red;
TheLED <pinBlue> blue;

//
//	Ну, а здесь пишем тоже самое, но не прямо,
//	а через переменные для пинов
//
void setup() {
	red.setMode(OUTPUT);
	blue.setMode(OUTPUT);
	blue.set(HIGH);	// синий изначально горит
}

void loop() {
	red.set(blue.get());	// Красный копируем с синего
	blue.set(! blue.get()); // А синий инвертируем
	delay(LightInterval);
}
//
//Скетч использует 1044 байт (3%) памяти устройства. Всего доступно 32256 байт.
//Глобальные переменные используют 9 байт (0%) динамической памяти, оставляя 2039 байт для локальных переменных. Максимум: 2048 байт.
//

Как видишь, с классом не то, что не больше, а даже меньше флеша. Почему меньше – это тебе на домашнее задание. Разбирайся.

anarch
Offline
Зарегистрирован: 10.09.2017

Хоть бы подсказали с какой стороны разбираться. Не в шаблонах ли дело?

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Тю! Да, шо такое? Тебе пример дай, да ещё разжуй его? Ты просил пример того, что использование классов не отжирает память? Ты его получил. Вот и любуйся на него. Пробуй поменять, посмотри, что получится. Шо ж всё что ли за тебя делать-то? так ты никогда ничего не поймёшь. Понимаешь. когда сам решаешь задачи, а не на дядю смотришь.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

как можно что-то понять не видя реального машинного кода )))

anarch
Offline
Зарегистрирован: 10.09.2017

ua6em пишет:

как можно что-то понять не видя реального машинного кода )))

еще и не зная ассемблер ))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

как можно что-то понять не видя реального машинного кода )))

anarch пишет:

еще и не зная ассемблер ))

А что он Вам даст? Там и так все понятно, смотреть надо внимательно. Как мне тут недавно тот же Ворота пенял (в другом, правда, контексте): "Рыба есть, ловить надо уметь" :)

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

А что он Вам даст? Там и так все понятно, смотреть надо внимательно. Как мне тут недавно тот же Ворота пенял (в другом, правда, контексте): "Рыба есть, ловить надо уметь" :)

повторюсь словами Деда - "Ваш лживый С++" )))

ЗЫ похоже врубился, в одном случае два раза получаем состояние пина, во втором, полученное ранее, просто инвертируем ?

astwo
Offline
Зарегистрирован: 10.07.2019

Это из серии что прямой путь не самый быстрый. Лучше ездить по дорогам чем напрямки, но пехом.

baby_in_Arduino
Offline
Зарегистрирован: 21.07.2019

ммм... а что на ардуинке с её то флешем в 32кб такие большие программы что надо городить ООП? ну сколько в среднестатистической программе для ардуинки кода? ну пусть 1000 строк, нафига там какое то ООП

Клапауций 003
Offline
Зарегистрирован: 20.07.2019

baby_in_Arduino пишет:
ммм... а что на ардуинке с её то флешем в 32кб такие большие программы что надо городить ООП? ну сколько в среднестатистической программе для ардуинки кода? ну пусть 1000 строк, нафига там какое то ООП

береста и лапти - наше всё.
пофиг, что эти лапти и бересту производим на автоматизированных линиях.
C++ объектно-ориентированный язык программирования
https://ru.m.wikipedia.org/wiki/C++

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

ЗЫ похоже врубился, в одном случае два раза получаем состояние пина, во втором, полученное ранее, просто инвертируем ?

Так может поступить только компилятор, который "клюшница делала". digitalRead - функция с побочным эффектом, её вызов игнорировать нельзя ни в каком случае: состояние пина-то могло и поменяться с прошлого вызова.

Да проще там всё, вы всё какие-то сложности ищете :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

baby_in_Arduino пишет:
ммм... а что на ардуинке с её то флешем в 32кб такие большие программы что надо городить ООП?

Ну, знаете, кто-то любит попа, кто-то попадью, а кто-то и на попову дочку заглядывается.

Одним ООП надо "городить", а для других он как дыхание и "городить" надо, когда вдруг пришлось обходиться без него.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

Да проще там всё, вы всё какие-то сложности ищете :)

пока не гляну код машинный
мне "лживый" С ваш не понять )))

Переменные для пинов как константы штоли?
(всё, других вариантов нет)

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

А разве переменные для пинов не абсолютно одинаково описаны в обоих случаях?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

baby_in_Arduino пишет:
ммм... а что на ардуинке с её то флешем в 32кб такие большие программы что надо городить ООП? ну сколько в среднестатистической программе для ардуинки кода? ну пусть 1000 строк, нафига там какое то ООП
Говнокодить можно и без знаниия ООП, Да и глубокое знания Си++ и ООП не мешает писать говнокод, не смотря что вики написано. Вот и многим быдлокодерам приходит мысль что ООП не нужен, говно писать можно и без него. На ардуине говнокод можно написать и в 10 строках.Что мы периодически каждый день и наблюдаем , причем даже флеша этот код много не займет.

 Что дает грамотное применение ООП- написать анатомически правильную программу. Ведь как природе,природа чуть-чуть подправила код и получился новый вид. И так постеменно появились более сложные формы жизни. И да литературы как написать анатомически правильную программу Вы не найдете. Максимум наметки или основные ошибки. Капитализм блин. Искусство написания анатомически правильной программы это ключевая технология в программировании, о которой прямо не положено говорить, потому что это коммерческая тайна.

anarch
Offline
Зарегистрирован: 10.09.2017

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

И не важно на 2 байта больше или на 8 меньше флеша скушает. Все больше и больше народу уже переходит на STM, ESP, туда где побольше памяти. Не хватило 32к возьмем 256к, на худой конец esp. А если ацки мега реальный проект то можно и малинку.

А ООП и призвано спрятать  анатомически не правильный говнокод от глаз обывателей в библиотеку.

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

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

anarch пишет:
Анатомически правильный или нет код это для обсуждения на форуме или за кружкой коньяка, важнее что бы он работал.
Ну да. Есть такая вещь как рак. Да человек живет, но как то не так.Слабость отдышка и другая дрянь. Вроде живой,вроде работает, а на деле через раз. Вот так и с программами. Конечно на больных программах можно заработать. Но больная программа это уже не конкурент здоровой. Анатомически правильная программа это есть здоровая программа, которая может "вырасти больше" и "дать потомство". Только демонстрашки обычно делают больными, что бы "не угнали".

anarch
Offline
Зарегистрирован: 10.09.2017

У каждого найдется шо полечить ;)

Говнокод может то же вырости и дать потомство. Посмотрите только на обилие библиотек.

baby_in_Arduino
Offline
Зарегистрирован: 21.07.2019

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

по сути это и есть ООП программа разбита на отдельные модули-подсистемы

посмотрите например на исходники операционной системы...

а лепить ключевое слово class и называть это ООП глупо, все можно написать на функциях без единого class и программа при этом будет модульной и объектно ориентированной

 

 

anarch
Offline
Зарегистрирован: 10.09.2017

Вы сейчас говорите о модульности. Это не ООП.

Да и посмотрите на исходники ядра Linux.

А если почитать создателя C++ там как раз таки на каждом углу табличка лепи class где только сможешь, а если не смог пытайся.

И я уже промолчу про это:

public class Program{ 
      
    public static void main (String args[]){
          
        System.out.println("Hello, World!");
    }
}

 

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

В воздухе явственно повеяло ООП-срачем. Позвонил в доставку попкорна. Обещали в течение получаса. Жду.

baby_in_Arduino
Offline
Зарегистрирован: 21.07.2019
или посмотрите утекшие исходники винды
все подсистемы представлены в виде объектов на чистом процедурном си
 
писать в идеологии ооп можно даже на голом си
можно даже на ассемблере
 
что нам дает сипипи в контексте ооп? синтаксический сахар и не более
 
 
baby_in_Arduino
Offline
Зарегистрирован: 21.07.2019

_

anarch
Offline
Зарегистрирован: 10.09.2017

Вся соль в этом синтаксическом сахаре )

Клапауций 003
Offline
Зарегистрирован: 20.07.2019

Ворота пишет:

В воздухе явственно повеяло ООП-срачем. Позвонил в доставку попкорна. Обещали в течение получаса. Жду.

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

как по мне ООП - оно уже есть. не хочешь - не пользуйся, ходи босиком по снегу.

anarch
Offline
Зарегистрирован: 10.09.2017

пока что призывов не было чистая полемика

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Клапауций 003 пишет:
уже есть. не хочешь - не пользуйся

"Вот вам любовь-морковь, не хочете - не ешьте" :)))

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

baby_in_Arduino пишет:
что нам дает сипипи в контексте ооп? синтаксический сахар и не более
Ну не знаю что вам дает. Может первитин.   Обычно переход на ООП дает переход от разработки программы в целом на разработку по компонентно. Причем уже отдельные компоненты могут разрабатывать разные группы разработчиков, или даже использовать уже готовые. Опять же форматы файлов это и есть появление зачатков ООП. И так далее ООП изподволь пролазит в жизнь. Хотим мы это или нет. Ну не живут долго компоненты у которых нет ООП структуры. И да можно делать ООП и без классов, но с классами все же удобнее. Ведь для этого классы и созданы.

anarch
Offline
Зарегистрирован: 10.09.2017

Морковь полезная даже если не хочешь нужно кушать xD

 

Вернусь опять к правильности кода.Нужно определиться что есть рабочий код.Возьмем тот же пример с мигалкой.И в одном и в другом случае достигнут результат, работает. Так какой из этих двух вариантов правильней?

А вот с точки зрения размера, да один больше требует ресурсов, а второй меньше.

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

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Клапауций 003 пишет:

...ходи босиком по снегу.

во, во, здоровее будешь )))

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

anarch пишет:

Вернусь опять к правильности кода.Нужно определиться что есть рабочий код.Возьмем тот же пример с мигалкой.И в одном и в другом случае достигнут результат, работает. Так какой из этих двух вариантов правильней?

оба неправильные, там на ассемлере десяток строк, и флэша минимум съест )))

anarch
Offline
Зарегистрирован: 10.09.2017

ua6em пишет:

Клапауций 003 пишет:

...ходи босиком по снегу.

во, во, здоровее будешь )))

и жуй морковку ))

Если добавить еще и ассемблер в обсуждение, война миров начнется...