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

Не создается объект производного класса

25.08.2017, 06:39. Просмотров 938. Ответов 24
Метки нет (Все метки)

Пожалуйста, помогите найти ошибку в коде. Не создается объект производного класса по выбору пользователя.

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#include<iostream>
#include<windows.h> 
#include<conio.h>
#include<string>
using namespace std;
 
enum Color { Black = 0, Blue, Green, Cyan, Red, Magenta, Brown, LightGray, DarkGray, LightBlue, LightGreen, LightCyan, LightRed, LightMagenta, Yellow, White };
 
HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); 
 
void setColor(Color text, Color background)
{
    SetConsoleTextAttribute(hStdOut, (WORD)((background << 4) | text));
}
 
void setCursor(int x, int y)
{
    COORD c = { x,y };
    SetConsoleCursorPosition(hStdOut, c);
}
 
void showMenu();
int choice();
 
class Toy
{
    string Name;
 
public:
    void inputName()
    {
        string N;
        cout << "Введите имя игрушки: ";
        cin >>N;
        setName(N);
    }
 
 
    void setName(string N)
    {
        Name = N;
    }
 
    string getName()
    {
        return Name;
    }
    virtual void voice() = 0;
};
 
class Cat : public Toy
{
    void voice()
    {
        cout << "Мяу-мяу!";
    }
};
 
 
class Dog :public Toy
{
public:
    void voice()
    {
        cout << "Гав-гав!";
    }
};
 
 
class Bird : public Toy
{
public:
    void voice()
    {
        cout << "Чирик-чирик!";
    }
};
 
void menuObj(Toy *&obj);
 
 
int main()
{
    setlocale(LC_ALL, "rus");
    Toy *obj(NULL); 
    menuObj(obj);
    obj->inputName();
 
    cout << "Меня зовут " << obj->getName() << endl;
    obj->voice();
}
 
 
void menuObj(Toy *&obj)
{
    setCursor(10, 10); cout << "Выберите игрушку:" << endl;
    showMenu();
 
    while (true) 
    {
        int n;
        n = choice();
 
        switch (n)
        {
        case 1:
            obj = new Cat(); 
            break;
        case 2:
            obj = new Dog();
            break;
        case 3:
            obj = new Bird();
            break;
                default:  
            continue; 
        }
        break; 
    }
}
 
 
void showMenu()
{
    string Menu[3] = { "Кошка", "Собачка", "Птичка"};
    int myCursor = 0;
    while (true)
    {
        //system("cls");
        setColor(White, Black);
        for (int i = 0; i < 3; ++i)
        {
            if (i == myCursor)
            {
                setColor(LightGreen, Black);
                setCursor(2, 12 + i);
                cout << Menu[i] << endl;
            }
            else
            {
                setColor(White, Black);
                setCursor(2, 12 + i);
                cout << Menu[i] << endl;
            }
        }
        setColor(White, Black);
 
        while (true)
        {
            if (GetAsyncKeyState(VK_UP) != 0)
            {
                myCursor--;
                if (myCursor == -1)
                {
                    myCursor = 3;
                }
                break;
            }
            else if (GetAsyncKeyState(VK_DOWN) != 0)
            {
                myCursor++;
                if (myCursor == 3)
                {
                    myCursor = 0;
                }
                break;
            }
        }
        Sleep(200);
    }
}
 
int choice()
{
    int n;
    int myCursor = 0;
    while (true)
    {
        if (GetAsyncKeyState(VK_UP) != 0)
        {
            myCursor--;
            if (myCursor == -1)
            {
                myCursor = 10;
            }
            break;
        }
        else if (GetAsyncKeyState(VK_DOWN) != 0)
        {
            myCursor++;
            if (myCursor == 10)
            {
                myCursor = 0;
            }
            break;
        }
        else if (GetAsyncKeyState(VK_RETURN))
        {
            n = myCursor;
            break;
        }
    }
    return n;
}
0
Лучшие ответы (1)
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.08.2017, 06:39
Ответы с готовыми решениями:

Почему объект производного класса не видит префиксный оператор из базового класса?
Короче создал я базовый класс с перегруженным префиксным оператором ++. Потом чтоб его...

Как сложить объект базового класса с объектом производного(наследуемого класса)
Как умножить объект базового класса с объектом производного(наследуемого класса): ozenka - объект...

Указатель на объект базового класса и адрес объекта производного класса
Пример кода: class Class1 { public: Class1(int x) { j = new int; *j = x; }...

как сделать чтобы объект производного класса сам себя добавлял в список или массив указателей базового класса?
я хотел так, но программа просто падает void Student::add(Base** head) { cout &lt;&lt; &quot;I here&quot; &lt;&lt;...

Не создается объект класса
Почему я не могу создать объект класса Zamovlena? Могу создать только указатель. Zamovlena.h...

24
nd2
3099 / 2593 / 1134
Регистрация: 29.01.2016
Сообщений: 8,690
25.08.2017, 07:05 2
Из showMenu() код как выходит?
1
Pupil_
0 / 0 / 1
Регистрация: 12.07.2017
Сообщений: 55
25.08.2017, 08:44  [ТС] 3
Функция showMenu только для отображения меню, а выбор пользователя - в функции choice(). В цикле переменной присваивается значение, возвращаемое функцией choice(), и в switch должен создаваться экземпляр соответствующего производного класса. Такова была логика. Только в чем ошибка, не могу понять.
0
Bretbas
Каждому свое
525 / 211 / 81
Регистрация: 05.08.2013
Сообщений: 1,611
Завершенные тесты: 2
25.08.2017, 08:56 4
Pupil_, А что за ошибка конкретно?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
class Cat : public Toy
{
    void voice()
    {
        cout << "Мяу-мяу!";
    }
};
 
 
class Dog :public Toy
{
public:
    void voice()
    {
        cout << "Гав-гав!";
    }
};
...
Область видимости voice() у Cat является private

void menuObj(Toy *&obj) это что? Вот так надо void menuObj(Toy *obj)
0
25.08.2017, 08:56
Alex5
1125 / 784 / 232
Регистрация: 12.04.2010
Сообщений: 2,012
25.08.2017, 11:48 5
Цитата Сообщение от Bretbas Посмотреть сообщение
void menuObj(Toy *&obj) это что?
Bretbas, внутри функции изменяется внешняя переменная, поэтому obj должна быть ссылкой.
C++
1
2
3
4
5
6
7
8
9
10
void menuObj(Toy *&obj)
{
    ... 
 
          obj = new Cat(); 
            break;
    ...
            obj = new Dog();
            break;
}
Добавлено через 3 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int choice()
{
    ....
    while (true)
    {
        if (GetAsyncKeyState(VK_UP) != 0)
        {
            ....
            //  break;    //  здесь не нужно  break
        }
        else if (GetAsyncKeyState(VK_DOWN) != 0)
        {
            ....
            //  break;    //  здесь не нужно  break
        }
        else  ....
        ....
}
Добавлено через 13 минут
Цитата Сообщение от Pupil_ Посмотреть сообщение
Функция showMenu только для отображения меню
Pupil_, добавьте точку останова в конце showMenu(), чтобы проверить, завершается ли когда-нибудь эта функция.
1
GbaLog-
Любитель чаепитий
3202 / 1503 / 472
Регистрация: 24.08.2014
Сообщений: 5,271
Записей в блоге: 1
Завершенные тесты: 2
25.08.2017, 16:08 6
Цитата Сообщение от Bretbas Посмотреть сообщение
Область видимости voice() у Cat является private
указатель там на Toy, так что так будет работать.
Цитата Сообщение от Bretbas Посмотреть сообщение
это что?
ссылка на указатель.
Цитата Сообщение от Bretbas Посмотреть сообщение
Вот так надо
не думаю.
в функцию бы хоть посмотрели.
0
nd2
3099 / 2593 / 1134
Регистрация: 29.01.2016
Сообщений: 8,690
25.08.2017, 16:56 7
Цитата Сообщение от Pupil_ Посмотреть сообщение
Функция showMenu только для отображения меню,
Я не спрашивал для чего она. Как выйти из этого цикла?
Цитата Сообщение от Pupil_ Посмотреть сообщение
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
while (true)
    {
        //system("cls");
        setColor(White, Black);
        for (int i = 0; i < 3; ++i)
        {
            if (i == myCursor)
            {
                setColor(LightGreen, Black);
                setCursor(2, 12 + i);
                cout << Menu[i] << endl;
            }
            else
            {
                setColor(White, Black);
                setCursor(2, 12 + i);
                cout << Menu[i] << endl;
            }
        }
        setColor(White, Black);
 
        while (true)
        {
            if (GetAsyncKeyState(VK_UP) != 0)
            {
                myCursor--;
                if (myCursor == -1)
                {
                    myCursor = 3;
                }
                break;
            }
            else if (GetAsyncKeyState(VK_DOWN) != 0)
            {
                myCursor++;
                if (myCursor == 3)
                {
                    myCursor = 0;
                }
                break;
            }
        }
        Sleep(200);
    }
1
Pupil_
0 / 0 / 1
Регистрация: 12.07.2017
Сообщений: 55
25.08.2017, 18:24  [ТС] 8
nd2, спасибо. Нужен выход из цикла при нажатии на клавишу Enter - правильно?
0
nd2
3099 / 2593 / 1134
Регистрация: 29.01.2016
Сообщений: 8,690
25.08.2017, 18:31 9
Цитата Сообщение от Pupil_ Посмотреть сообщение
Нужен выход из цикла при нажатии на клавишу Enter - правильно?
Это уж, как ты решишь.
1
Bretbas
Каждому свое
525 / 211 / 81
Регистрация: 05.08.2013
Сообщений: 1,611
Завершенные тесты: 2
26.08.2017, 08:36 10
Alex5, GbaLog-, Так если, я напишу вот так:
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
60
61
62
63
64
65
66
67
68
69
class Toy
{
public:
    virtual void setValue( int value ) = 0;
    virtual int getValue() const = 0;
};
 
class Cat : public Toy
{
public:
    void setValue( int value ) override
    {
        _value = value * 2;
    }
    
    int getValue() const override
    {
        return _value;
    }    
private:
    int _value;
};
 
 
class Dog :public Toy
{
    void setValue( int value ) override
    {
        _value = value * 3;
    }
    
    int getValue() const override
    {
        return _value;
    }    
private:
    int _value;   
};
 
 
class Bird : public Toy
{
    void setValue( int value ) override
    {
        _value = value * 4;
    }
    
    int getValue() const override
    {
        return _value;
    }    
private:
    int _value;    
};
 
void func( Toy* toy )
{
    // Тут тоже изменяется же внешнее представление toy
    toy -> setValue( 2 );
}
 
int main()
{
    Toy* toy = new Bird();
    func( toy );
    std :: cout << toy -> getValue();
    
    return 0;
}
То по идее в func( Toy* toy ) тоже изменяется внешнее представление переменной toy? Или нет? Или если изменяется полностью представление объекта, как указатель на другой класс-наследник, то нужно передавать по ссылке, а если изменяется только определенные члены в классе, то можно просто по указателю?
0
GbaLog-
Любитель чаепитий
3202 / 1503 / 472
Регистрация: 24.08.2014
Сообщений: 5,271
Записей в блоге: 1
Завершенные тесты: 2
26.08.2017, 09:27 11
Bretbas, там в функции указатель изменяется.
без передачи по ссылке в вызывающей функции он так и останется не измененным.
1
Bretbas
Каждому свое
525 / 211 / 81
Регистрация: 05.08.2013
Сообщений: 1,611
Завершенные тесты: 2
26.08.2017, 09:34 12
GbaLog-, ага, понял. Спасибо. Что-то затупил
0
bormant
Модератор
Эксперт Pascal/DelphiЭксперт NIX
5139 / 3030 / 2292
Регистрация: 22.11.2013
Сообщений: 8,477
26.08.2017, 10:09 13
Функции виртуальные, все ожидаемо работает, что не так-то?
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
#include <iostream>
 
class Toy {
public:
    virtual void setValue( int value ) = 0;
    virtual int getValue() const = 0;
};
 
class Bird : public Toy {
    void setValue( int value ) override { _value = value * 4; }
    int getValue() const override { return _value; }    
private:
    int _value;    
};
 
void func( Toy *toy ) {
    toy->setValue( 2 );
}
 
int main() {
    Toy* toy = new Bird();
    func( toy );
    std::cout << toy->getValue();
    return 0;
}
Прогон:
Код
8
Добавлено через 3 минуты
Если не считать, что getValue() не нужен виртуальный, по крайней мере в этом примере...
0
GbaLog-
Любитель чаепитий
3202 / 1503 / 472
Регистрация: 24.08.2014
Сообщений: 5,271
Записей в блоге: 1
Завершенные тесты: 2
26.08.2017, 10:15 14
Цитата Сообщение от bormant Посмотреть сообщение
что не так-то?
этот пример с кодом ТС никак не сопоставим.
он работает, а код ТСа так работать не будет.
попробуйте в func поменять значение указателя так, чтобы в вызывающей функции указатель тоже поменялся.
0
bormant
Модератор
Эксперт Pascal/DelphiЭксперт NIX
5139 / 3030 / 2292
Регистрация: 22.11.2013
Сообщений: 8,477
26.08.2017, 10:17 15
GbaLog-,
указатель в func( Toy* ) не меняется -- что передали, за то и дёрнули.

Добавлено через 1 минуту
Код ТС-а без виртуального наследования работать не будет -- по типу родителя вызывать методы наследников не выйдет.
0
Pupil_
0 / 0 / 1
Регистрация: 12.07.2017
Сообщений: 55
26.08.2017, 10:56  [ТС] 16
Простите, а можно вернуться к моему коду? Я окончательно туплю. Из цикла выйти не могу.
Если добавить, например, такое
C++
1
2
int input;
input= _getch();
и условием выхода из цикла поставить
C++
1
input!=13
то в начале выполнения - задержка до нажатия клавиши. Если нажать любую - то проблема осталась та же, а если Enter -
то меню вообще пропускается и переход сразу к вводу имени. Помогите, пожалуйста.
0
GbaLog-
Любитель чаепитий
3202 / 1503 / 472
Регистрация: 24.08.2014
Сообщений: 5,271
Записей в блоге: 1
Завершенные тесты: 2
26.08.2017, 10:57 17
Цитата Сообщение от bormant Посмотреть сообщение
указатель в func( Toy* ) не меняется -- что передали, за то и дёрнули.
у ТС меняется, поэтому этот пример и не подходит под случай ТС.
Цитата Сообщение от bormant Посмотреть сообщение
Код ТС-а без виртуального наследования работать не будет
будет.
http://rextester.com/SIQW39483
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
60
61
62
63
64
65
66
67
68
69
70
71
72
#include<iostream>
#include<string>
using namespace std;
 
void showMenu();
int choice();
 
class Toy
{
    string Name;
 
public:
    virtual ~Toy() {}
    void inputName()
    {
        string N;
        cout << "Введите имя игрушки: ";
        cin >>N;
        setName(N);
    }
 
 
    void setName(string N)
    {
        Name = N;
    }
 
    string getName()
    {
        return Name;
    }
    virtual void voice() = 0;
};
 
class Cat : public Toy
{
    void voice()
    {
        cout << "Мяу-мяу!";
    }
};
 
 
class Dog :public Toy
{
public:
    void voice()
    {
        cout << "Гав-гав!";
    }
};
 
 
class Bird : public Toy
{
public:
    void voice()
    {
        cout << "Чирик-чирик!";
    }
};
 
 
int main()
{
    setlocale(LC_ALL, "rus");
    Toy *obj = new Bird;
    obj->inputName();
 
    cout << "Меня зовут " << obj->getName() << endl;
    obj->voice();
}
а вот то, что у Toy нет виртуального деструктора - это плохо.
1
Pupil_
0 / 0 / 1
Регистрация: 12.07.2017
Сообщений: 55
26.08.2017, 11:15  [ТС] 18
Похоже, что мое прошлое сообщение (немного выше) потерялось в споре уважаемых программистов...

Не создается объект производного класса

Пожалуйста, помогите - как это можно исправить?
0
bormant
Модератор
Эксперт Pascal/DelphiЭксперт NIX
5139 / 3030 / 2292
Регистрация: 22.11.2013
Сообщений: 8,477
26.08.2017, 13:29 19
Цитата Сообщение от GbaLog- Посмотреть сообщение
будет
Ага, щаз ;-):
C++
1
    virtual void voice() = 0;
Ну а getName() возвращает то, что лежит внутри объекта (его данные, установленные разными конструкторами), но код один и тот же -- Toy::getName().

Про "виртуальное наследование" -- был неточен, имел в виду вынос разного кода наследников в виртуальные функции, а не
C++
1
class Derived : public virtual Base
0
GbaLog-
Любитель чаепитий
3202 / 1503 / 472
Регистрация: 24.08.2014
Сообщений: 5,271
Записей в блоге: 1
Завершенные тесты: 2
26.08.2017, 13:41 20
я всё равно не понял, что вы хотели сказать.
0
26.08.2017, 13:41
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.08.2017, 13:41

Не создается объект класса
Только изучаю плюсы. Натолкнулся на непонятное поведение конструктора. Попробовал 2 варианта: ...

Создается объект абстрактного класса:(
Вот допустим у меня есть класс: class Cell { public: Cell() {} ~Cell() {} virtual...

4 раза в памяти создается объект класса
Доброго времени суток! Есть следующий код: #include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include...


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

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

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