можно ли создать объект класса в методе класса?

valeryich
Offline
Зарегистрирован: 29.02.2020

Функция получает результат, обрабатывая свойства объектов класса.
Можно ли такую функцию разместить внутри класса?

Например, допустима ли такая конструкция:

  
    class A {
       int _x;
      
       public:
       A a(int x);
       int summa;
       void  method1();
       void  method2summ();      
    }
          A::A(int x) { _x=x;}
    void  A::method1(){ _x++;}
    void  A::method2summ(){
           static  A a1(0);
           static  A a2(0);
           static  A a3(0);
           a1.method1();
           a2.method1();
           a3.method1();
           summa = a1._x + a2._x + a3._x ;
           }
        ........................................
            A a0(0);
         void loop() {
          a0.method2summ(); 

В примере method2summ(); считает сумму свойств трёх объектов класса.
К следующему вызову этой функции свойства сохранят последние принятые ими значения?

 

valeryich
Offline
Зарегистрирован: 29.02.2020

конструктор A А(int x);

ещё раз код:

class A {
       int _x;
      
       public:
       A A(int x);
       int summa;
       void  method1();
       void  method2summ();      
    }
          A::A(int x) { _x=x;}
    void  A::method1(){ _x++;}
    void  A::method2summ(){
           static  A a1(0);
           static  A a2(0);
           static  A a3(0);
           a1.method1();
           a2.method1();
           a3.method1();
           summa = a1._x + a2._x + a3._x ;
           }
        ........................................
            A a0(0);
         void loop() {
          a0.method2summ(); 
          ...........          
         }

 

valeryich
Offline
Зарегистрирован: 29.02.2020

и еще раз:

    class A {
       int _x;
      
       public:
       A A(int x);
       int summa;
       void  method1();
       void  method2summ();      
    };
          A::A(int x) { _x=x;}
    void  A::method1(){ _x++;}
    void  A::method2summ(){
           static  A a1(0);
           static  A a2(0);
           static  A a3(0);
           a1.method1();
           a2.method1();
           a3.method1();
           summa = a1._x + a2._x + a3._x ;
           }

void setup() {
  // put your setup code here, to run once:

}

void loop() {
           A a0(0);
          a0.method2summ(); 

}

 

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

valeryich,

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

Ответ на вопрос из заголовка - конечно, можно, другой вопрос как и зачем.

В пятой строке первого кода написано что-то непонятное. Имя метода/свойства (кроме конструкторов) не может совпадать с именем класса. Прямое указание текущего класса в качестве типа в этом месте невозможно, т.к. класс ещё не определён. Что Вы имели в виду этой записью? Вы бы хоть комментировали!

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

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

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

valeryich
Offline
Зарегистрирован: 29.02.2020

b707 пишет:

 бесконечная рекурсия, вам это в голову не приходило?

Вы не правы. Чтобы в двух зеркалах появилась бесконечная череда отражений, нужно эти зеркала для начала поставить нужным образом. То, что у Вас есть два зеркала - вовсе не означает, что это случится.
Бесконечная рекурсия появится, только если Вы для внутренних объектов метода вызовите этот метод.
В моём примере Для 

static  A a1(0);
14 static  A a2(0);
15 static  A a3(0);

нужно вызвать void  method2summ(); 
.....a1.
method2summ();
Если этого не делать - рекурсии не случится.

valeryich
Offline
Зарегистрирован: 29.02.2020

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

пятой строке первого кода написано что-то непонятное. 

Да, орфография страдает. Создаю второй класс в жизни. Извините. Это было описание конструктора.

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

валерич, у вас рекурсия будет вот тут, в пятой строчке:

class A {
       int _x;
      
       public:
       A A(int x);
       int summa;
       void  method1();
       void  method2summ();      
    };

Эта строка создает новый обьект класса А (наховем его А_1)внутри обьекта А.  В моменет создания этого обьекта А_1 в нем, в свою очередь, тоже будет создан обьект типа А - назовем его А_2. А в момент создания обьекта А_2 в нем будет создан обьект А_3....

ну дальше вы поняли

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

valeryich пишет:

Да, орфография страдает. Создаю второй класс в жизни. Извините. Это было описание конструктора.

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

valeryich
Offline
Зарегистрирован: 29.02.2020

b707 пишет:

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

В том то и дело, что я пытаюсь обойтись одним классом, без вложенных.
Кнопка, и способ обработки её сигнала - объект класса.
Четыре кнопки - четыре объекта.
Но мне нужно сделать опрос всех кнопок, исключить лишние комбинации кнопок, получить НОМЕР НАЖАТОЙ КНОПКИ,  и ещё кое-чего, в одной короткой строчке верхней программы.

типа readButton4();

Убрав весь длинный код с глаз долой.
Я должен сделать функцию, обрабатывающую свойства объектов класса.
И хочу засунуть её внутрь класса.

valeryich
Offline
Зарегистрирован: 29.02.2020

Прикольно, но этот код скомпилировался без ошибок:
_
 

class A {
       int _x;
      
       public:
       A(int x);
       int summa;
       void  method1();
       void  method2summ();      
    };
          A::A(int x) { _x=x;}
    void  A::method1(){ _x++;}
    void  A::method2summ(){
           static  A a1(0);
           static  A a2(0);
           static  A a3(0);
           a1.method1();
           a2.method1();
           a3.method1();
           summa = a1._x + a2._x + a3._x ;
           }

void setup() {
  // put your setup code here, to run once:

}

void loop() {
           A a0(0);
          a0.method2summ(); 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Вот вы сидите, набиваете буквы, нажимая на кнопки, собранные в клавиатуру. И не испытываете никакого диссонанса по поводу того, что кнопки не собраны в КНОПКУ. Что вам мешает собрать экземпляры класса "кнопка" в класс "клавиатура"?

Необходимо ли наделять класс "кнопка" безумным количеством горизонтальных связей и нечеловеческой логики для описания матрицы допустимых состояний?

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

sadman41 пишет:
Вот вы сидите, набиваете буквы, нажимая на кнопки, собранные в клавиатуру. И не испытываете никакого диссонанса по поводу того, что кнопки не собраны в КНОПКУ. Что вам мешает собрать экземпляры класса "кнопка" в класс "клавиатура"?

+100.

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

 

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

valeryich пишет:

Я должен сделать функцию, обрабатывающую свойства объектов класса.

Кому же это Вы, интересно, так задолжали?

valeryich пишет:

хочу засунуть её внутрь класса.

Хотите, так засовывайте! Пока же я вижу только мышей, которые плачут, но продолжают грызть кактус :-)

valeryich
Offline
Зарегистрирован: 29.02.2020

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

Хотите, так засовывайте! Пока же я вижу только мышей, которые плачут, но продолжают грызть кактус :-)

Я начинающий в с++, хочу попробовать все варианты. Что в этом плохого?

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

valeryich пишет:

Я начинающий в с++, хочу попробовать все варианты. Что в этом плохого?

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

Azathtot
Offline
Зарегистрирован: 17.03.2020

valeryich пишет:

Я начинающий в с++, хочу попробовать все варианты. Что в этом плохого?

На ардуине вы С++ не выучите.  Только "Си с классами". Хотите изучать С++ - учите на нормальной платформе. Правда как следствие - вы начнете ненавидеть Arduino :)

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

Azathtot пишет:

На ардуине вы С++ не выучите.  Только "Си с классами". Хотите изучать С++ - учите на нормальной платформе. Правда как следствие - вы начнете ненавидеть Arduino :)

О. опять "нечестный Си"....а давайте вы расскажете, чем "С++ с классами" в Ардуино отличается от "настоящего"

Azathtot
Offline
Зарегистрирован: 17.03.2020

b707 пишет:

О. опять "нечестный Си"....а давайте вы расскажете, чем "С++ с классами" в Ардуино отличается от "настоящего"

Отсутствием STL (коя является неотъемлимой частью С++). Отсутствием new [] delete []. 
Отсутствием обработки исключений. 
Уточню. Сам лично являюсь поклонником event-driven архитектуры, которая на задачи реально времени ложится достаточно не плохо.  Соотвественно предпочитаю, что бы допустим прерывание порожало некое событие (со своим приоритетом конечно), которе будет "разребено" в основном цикле. Так вот, такие шаблоны как queue в эту модель ложаться отлично, и так же вызовы new и delete для структур, описывающих событие ну очень как удобны.
 

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Azathtot пишет:

Отсутствием STL (коя является неотъемлимой частью С++).

1. STL не является неотъемлемой частью С++, просто потому, что не входит в язык - это library, написанная на языке С++, всего лишь. Стандартная шаблонная библиотека, не более того. Говорить, что она является неотъемлемой частью - неверно. Отнять её - как два пальца, и С++ этого даже не заметит;

2. Есть порт: https://www.arduinolibraries.info/libraries/arduino-stl

 

Azathtot пишет:

Отсутствием new [] delete []

void setup()
{
	uint8_t* arr = new uint8_t[10];
	delete[] arr;
}

void loop()
{
	
}

Компилируется и работает, как положено. Как оно там унутре устроено - дело десятое.

Azathtot пишет:

Отсутствием обработки исключений

Что да, то да - там флаг компилера -fno-exceptions (по памяти) выставлен. Впрочем, сама по себе обработка исключений - очень дорогостоящая операция, и, пмсм, не слишком хорошо ложиться на концепцию микроконтроллеров. Короче - можно легко жить и без try/catch/throw. Не стоит все фишки взрослых систем без оглядки тащить на МК, как мне кажется.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Azathtot пишет:

Уточню. Сам лично являюсь поклонником event-driven архитектуры, которая на задачи реально времени ложится достаточно не плохо.  Соотвественно предпочитаю, что бы допустим прерывание порожало некое событие (со своим приоритетом конечно), которе будет "разребено" в основном цикле. Так вот, такие шаблоны как queue в эту модель ложаться отлично, и так же вызовы new и delete для структур, описывающих событие ну очень как удобны.

И что мешает юзать этот подход, собственно? Правильный ответ - ни-че-го. Юзайте, кто мешает? Нужно, чтобы всё разгребалось в основном цикле - делаете очередь, диспетчера, подписчиков, пр. - и вперёд. При чём тут якобы нечестный С++ - непонятно.

sadman41
Offline
Зарегистрирован: 19.10.2016

Мне вот интересно - C++ появилось во время каких контроллеров?
Сложно представить, что необходимость кидать эксэпшн по любому поводу потребовалась для программирования какой-нить тиньки с 64байт ОЗУ.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:
Мне вот интересно - C++ появилось во время каких контроллеров? Сложно представить, что необходимость кидать эксэпшн по любому поводу потребовалась для программирования какой-нить тиньки с 64байт ОЗУ.

Да это просто переживания разработчика взрослых систем, который ВНЕЗАПНО обнаружил, что привычного ему инструмента - сп@здили, вернее - недоложили. Имхо. 

Ничего, пообвыкнется, и поймёт, что тут - свои подходы и инструментарий ;)

Azathtot
Offline
Зарегистрирован: 17.03.2020

DIYMan пишет:

Ничего, пообвыкнется, и поймёт, что тут - свои подходы и инструментарий ;)

Да я уже давно "обвыкся". Просто не пишу под микроконтроллеры на С++, ввиду его высокой ресурсоемкости. 
Для них достаточно Pure C. 
Хотя да, по началу пытался натянуть сову на глобус - создать свою билиотеку с конструкторами и  деструкторами, правда потом по здравому разумению это бросил.
А С++ появился когда на дворе был 8051 и бородатые мужики кодили под него на асме :)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Azathtot пишет:

Да я уже давно "обвыкся". Просто не пишу под микроконтроллеры на С++, ввиду его высокой ресурсоемкости. 

Для них достаточно Pure C.

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

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

DIYMan пишет:
STL ... не входит в язык

Спорный вопрос. Как "язычник", я 100% согласен, но в стандарте языка STL описана.

А так, да, тема опять скатывается к "честный - нечестный" :-)

Кстати, как там насчёт STL, исключений и всего остального в изначальном описании языка от Страуструпа?

sadman41
Offline
Зарегистрирован: 19.10.2016

Azathtot пишет:

А С++ появился когда на дворе был 8051 и бородатые мужики кодили под него на асме :)


А применялся на каких? Т.е. понятно, что можно пытаться любой язык к любому камню прикладывать, но целевой системой для C±± что было, какой производительностью обладало? Не мог же разумный человек разрабатывать язык для абстрактных нужд.

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

Када я начинал программировать 8031, никаких С++ для него в помине не было.