Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.56/9: Рейтинг темы: голосов - 9, средняя оценка - 4.56
Sergey271
0 / 0 / 0
Регистрация: 22.09.2014
Сообщений: 28
1

Создать объект внутри класса, который может вызывать функцию этого класса

12.11.2014, 07:16. Просмотров 1815. Ответов 6
Метки нет (Все метки)

Ребята помогите уже несколько дней мучаюсь. Хочу сделать программу в консоле демонстрации работы лифта в здании 2 этажа. Сделал класс Кнопка и класс Лифт. Кнопка есть на этаже и кнопка есть в лифте. Так вот кнопка в лифте не хочет никак работать. В функцию buttonPress мы передаем ссылку на объект класса Лифт. И из этой функции уже вызываем функцию ComeGetMe объекта Лифт.В этом месте у меня ругается пишет expected и все. А чего ожидает не понятно. Кто подскажет в чем проблема?
Код ниже:

Класс Лифт
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
#ifndef LIFT_H
#define LIFT_H
 
#include "Doors.h"
#include "Buttons.h"
//#include "Ring.h"
 
class Lift{
public:
    Lift();
 
    void comeGetMe(int);
 
    Buttons bt1;
    Buttons bt2;
private:
 
 
    int getFloor();     //показать этаж
    void setFloor(int);
 
    void setFull(int );//занять освободить лифт пассажиром
    bool getFull();
 
    Doors Door;
//  Ring rin;
 
    bool full; //занят = 1 свободен = 0
    int floor; //текущий этаж
 
 
};
#endif;
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include "Lift.h"
 
#include <iostream.h>
#include <time.h>
 
Lift::Lift(): bt1(1),bt2(2)
{
    setFull(0);
    setFloor(1);
}
 
void Lift::setFull(int n)//занять освободить лифт пассажиром
{
    if ((n < 0) && (n > 1)) n = 0;
    full = n;
 
}
 
bool Lift::getFull()     //состояние полный или пустой
{
    return full;
}
 
void Lift::setFloor(int n)//установить этаж
{
    if (n < 1 && n > 2) n = 1;
    floor = n;
}
 
int Lift::getFloor()     //показать этаж
{
    return floor;
}
 
void sleep(int t)
{
    t += time(NULL);
    while (t > time(NULL)){};
 
}
 
void Lift::comeGetMe(int f)     //показать этаж
{
    if (f < 1 && f > 2) {
        cout << "ERROR not valid button\n ";
        f=1;
    }
 
    if (Door.GetDoors()==1) {
        Door.CloseDoors();
    }
 
    if (getFloor() != f) {
        cout <<"lift move on the " << f << " floor!\n";
        setFloor (f);
    }
    Door.OpenDoors();
 
}
Класс Кнопка
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef BUTTONS_H
#define BUTTONS_H
#include "Lift.h"
 
class Buttons{
public:
    Buttons(int);
    void pushButton(Lift &);// Нажатие на кнопку
    void resetButton();
    bool GetButton();
private:
    bool status;// 1 нажата 0 отпущена
    int floor;
};
#endif;
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
#include "Buttons.h"
#include <iostream.h>
 
Buttons::Buttons(int n)
{
    floor = n;
    resetButton();
}
void Buttons::pushButton(Lift &)
{
    cout << "Pressed button" << floor << endl;
    status = 1;             //кнопка становиться нажата
    lif.comeGetMe(floor);       //вызывается лифт и говорит ему свой этаж
}
 
void Buttons::resetButton()
{
    cout << "Reset button" << floor << endl;
    status = 0;
}
 
bool Buttons::GetButton()
{
    cout << "Button status\n" << status << endl; // 1 нажата 0 отпущена
    return status;
}
Драйвер проверки работы
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream.h>
#include <Lift.h>
//#include <Buttons.h>
 
main()
{
    Lift l;
   //   Buttons b1(1),b2(2);
 
 // b1.pushButton(l);
    l.bt1.pushButton(l);
 
 // l.comeGetMe(2);
 // l.comeGetMe(1);
 
 
 
    system("pause");
    return 0;
}
Добавлено через 12 часов 34 минуты
Также создан класс этаж который включает в себя класс кнопку. Неужели никто не сталкивался с такой проблемой?

Добавлено через 2 часа 25 минут
Частично помогла такая конструкция в хедере лифта
C++
1
2
3
 
Buttons *bt1;
Buttons *bt2;
Как я понимаю в объекте резервируется 2 место под указатели на объект типа кнопка. Как теперь передать ссылку на объект кнопка в конструктор лифта да еще чтобы он эту ссылку записал в bt1 например?
Такое решение мне не нравиться потому что, я создаю объект лифт и хочу чтобы кнопки уже автоматически в этом объекте присутствовали, а не создавать еще отдельно кнопки.
Тут форум для монологов похоже сам себе задаю вопросы и сам же отвечаю
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.11.2014, 07:16
Ответы с готовыми решениями:

Создание статической функции класса, которая принимает экземпляр этого же класса как объект
Привет. Есть такой код class Model { public: Model(); Model(int...

Индексация массива класса, через объект этого класса
class A{ char c;//? - размер массива public: A(int C){c;} }; int...

В конструктор класса передать объект этого класса
Вопрос на засыпку :) Как в конструктор класса передать объект этого класса?...

Статический указатель класса на объект этого же класса
Не пойму: что в этом коде не так? #include &lt;iostream&gt; #include &lt;cstdlib&gt; ...

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

6
Cookie Monster
16 / 16 / 6
Регистрация: 03.11.2014
Сообщений: 71
12.11.2014, 07:29 2
Как минимум надо тут исправить
C++
1
2
3
4
5
6
void Buttons::pushButton(Lift & lift)
{
    cout << "Pressed button" << floor << endl;
    status = 1;             //кнопка становиться нажата
    lift.comeGetMe(floor);       //вызывается лифт и говорит ему свой этаж
}
Добавлено через 11 минут
Если в классе есть конструктор отличный от конструктора по умолчанию то надо этот самый конструктор по умолчанию определить.
1
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4800 / 2452 / 686
Регистрация: 18.10.2014
Сообщений: 4,220
12.11.2014, 07:46 3
Лучший ответ Сообщение было отмечено Sergey271 как решение

Решение

Цитата Сообщение от Sergey271 Посмотреть сообщение
Кто подскажет в чем проблема?
Заголовочные файлы 'Buttons.h' и 'Lift.h' включают друг друга циклически. Сразу понятно, что получатся "непонятные" ошибки. Циклическое включение заголовочных файлов никогда не имеет смысла.

Именно это произошло в вашем случае. Циклическое включение "разрешилось" так, что 'Buttons.h' включился выше, а 'Lift.h' - ниже. В результате тип 'Lift' оказался неизвестным на территории 'Buttons.h' и компилятор ругается на него.

В данном случае надо убрать из 'Buttons.h' включение 'Lift.h', а вместо этого просто поместить в 'Buttons.h' предварительное объявление класса 'Lift'

C++
1
2
3
4
5
6
7
#ifndef BUTTONS_H
#define BUTTONS_H
 
class Lift;
 
class Buttons{
  ...
А вот уже в 'Buttons.cpp' можно смело включать 'Lift.h', чтобы внутри 'Buttons.cpp' сделать 'Lift' завершенным типом.

Остальные заголовочные файлы надо тоже проверить на предмет циклического включения. Возьмите за правило: заголовочные файлы в программе должны образовывать однозначную иерархию уровней. Заголовочные файлы более высокого уровня имеют право включать только заголовочные файлы более низкого уровня, но не наоборот.

В данном случае класс 'Lift' напрямую содержит внутри себя подобъекты типа 'Buttons'. Это означает, что 'Buttons.h' имеет более низкий уровень, а 'Lift.h' - более высокий уровень. Следовательно запрещается включать 'Lift.h' в 'Buttons.h'. Включайте 'Buttons.h' в 'Lift.h', а в самом 'Buttons.h' обходитесь такими предварительными декларациями классов, как я показал выше.

Добавлено через 4 минуты
Цитата Сообщение от Cookie Monster Посмотреть сообщение
Если в классе есть конструктор отличный от конструктора по умолчанию то надо этот самый конструктор по умолчанию определить.
Что значит "надо определить"? Его "надо определить", если он нужен согласно замыслу автора кода. Но в данном случае он не нужен. Нигде в программе не используется конструктор по умолчанию класса 'Buttons'.
1
Sergey271
0 / 0 / 0
Регистрация: 22.09.2014
Сообщений: 28
12.11.2014, 08:59  [ТС] 4
"Пацаны вообще ребята!" заработало!

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

Cookie Monster тебе тоже спасибо за ответ. я попробовал так
C++
1
void Buttons::pushButton(Lift & lift)
и так
C++
1
void Buttons::pushButton(Lift &lift)
оба варианта работают, но второй вариант мне думается более правильный. Это похоже на то как некторые указатели объявляют
C++
1
int* имя
вместо
C++
1
int *имя
Конструктор по умолчанию не могу определить для кнопки так как это логически не правильно, ведь в жизни каждая кнопка отвечает за один этаж.
0
Cookie Monster
16 / 16 / 6
Регистрация: 03.11.2014
Сообщений: 71
12.11.2014, 09:12 5
Ну да неправильно выразился.я бы такой простой конструктор написал сразу а если потом он потребуется то он уже есть
Ничто не мешает сделать по умолчанию кнопкой первого этажа :-Р

Добавлено через 7 минут
Хотя получится что это частный случай другого конструктора и скорее всего не нужен.
в общем я был неправ
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
4800 / 2452 / 686
Регистрация: 18.10.2014
Сообщений: 4,220
12.11.2014, 09:45 6
Цитата Сообщение от Sergey271 Посмотреть сообщение
теперь мне все ясно по предварительным описаниям классов, можно делать два класса включающие себя друг в друга.
Ну в буквальном прямом смысле два класса не могут включать в себя друг друга. Такое взаимное включение, если бы оно было возможным, приводило бы к бесконечному рекурсивному включению и возникновению класса бесконечно большого размера.

Один класс может буквально содержать другой (как Lift содержит Buttons), но при этом последний может только ссылаться на первый через указатели или ссылки. Вот для того, который "ссылается через указатели или ссылки" достаточно только предварительного объявления того класса, на который он ссылается (как для Buttons достаточно только предварительного объявления Lift)

Поэтому при разработке такой "зацикленной" системы классов надо всегда сначала принять решение, какой класс будет "главным" (т.е. сможет напрямую включать другие классы), а какой класс будет "второстепенным" (т.е. сможет только ссылаться на главный класс).
0
aLarman
646 / 567 / 164
Регистрация: 13.12.2012
Сообщений: 2,123
Завершенные тесты: 2
12.11.2014, 15:28 7
Цитата Сообщение от Sergey271 Посмотреть сообщение
Это похоже на то как некторые указатели объявляют
не имеет значения как их объявить
0
12.11.2014, 15:28
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.11.2014, 15:28

Правда, что указатель класса-наследника не может указывать на объект класса-родителя?
Доброго времени суток! Пример кода ниже. Правда ли , что указатель...

Можно ли создать объект класса с таким же именем как у самого класса?
Можно ли создать объект класса с таким же именем как у самого класса? Ну или...

В конструкторе вложенного класса инициализируется приватное поле. Потом вызывается функция-метод этого класса и выводит значение этого поля НО НЕ ТО!
Друзья! Почему так? #include &lt;windows.h&gt; #include &lt;iostream&gt; using namespace...


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru