Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.62/13: Рейтинг темы: голосов - 13, средняя оценка - 4.62
0 / 0 / 1
Регистрация: 01.11.2011
Сообщений: 26
1

Наследование и виртуальные функции

19.09.2013, 14:50. Показов 2688. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго времени суток. Есть два вопроса:

1) Подскажите, плиз, что делаю не так. Есть базовый класс human и класс наследник solder. Если вызывать методы setName и setAge из наследника solder, то они не будут работать. Почему?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class human {
    
    public: 
        void information() {
            cout << "My name is " << name << ". My age is " << age << endl;
        }
 
        void setAge(int set_age) {
            age = set_age;
        }
        
        void setName(string set_name) {
            name = set_name;
        }
    private:
        string name;
        int age;
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
class solder : public human {
        
    public: 
 
        void information() {
            cout << "I am solder! My name is " << name << " and my age is " << age << endl;
        }
        
    private:
        string name;
        int age;
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int main() {
 
human *alex = new human;
 
alex->setName("Alex");
alex->setAge(25);
alex->information();
 
delete alex;
 
solder *ivan = new solder();
 
ivan->setName("Ivan");
ivan->setAge(20);
ivan->information();
 
delete ivan;
return 0;
}
Результат работы программы:
My name is Alex. My age is 25
I am solder! My name is and my age is 0


2) В классе наследнике функция information() перегружается и в итоге имеем другой результат для класса наследника. В чем тогда отличие между таким способом изменения результата в наследнике и если бы функция information() была объявлена как virtual в классе human и в наследнике была бы переопределена?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.09.2013, 14:50
Ответы с готовыми решениями:

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

Виртуальные функции и наследование
в общем есть исходный класс shape- фигура в которой определены 2 виртуальные функции инициализации...

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

Наследование и виртуальные функции
Всем здарова. Есть пару косяков в коде, но я их не могу найти. Быть может вы найдёте их? Вот код:...

8
35 / 35 / 7
Регистрация: 02.05.2013
Сообщений: 109
19.09.2013, 15:02 2
потому что вы не объявили их виртуальными
C++
1
virtual void information();

здесь:
C++
1
2
3
ivan->setName("Ivan");
ivan->setAge(20);
ivan->information();
вы меняет значения в базовом классе, потом выводите значения производного класса
0
250 / 232 / 46
Регистрация: 05.02.2010
Сообщений: 3,288
19.09.2013, 15:05 3
конструктор есть где то ?
0
0 / 0 / 1
Регистрация: 01.11.2011
Сообщений: 26
19.09.2013, 15:17  [ТС] 4
А чтобы использовать функции setName() и setAge() для класса наследника, то нужно их тоже объявить виртуальными и переопределить в наследнике?
0
35 / 35 / 7
Регистрация: 02.05.2013
Сообщений: 109
19.09.2013, 15:28 5
В Вашем конкретном примере путаница вызвана тем, что в производном классе есть такие же данные члены, к которым в обращаетесь в information().
Имхо, дублирование данных лишнее, нужно просто убрать данные из производного класса и всё.

Цитата Сообщение от qazc Посмотреть сообщение
А чтобы использовать функции setName() и setAge() для класса наследника, то нужно их тоже объявить виртуальными и переопределить в наследнике?
если вы собираетесь их переопределять и/или использовать указатель на базовый класс, инициализированный указателем на производный класс, то функции нужно сделать виртуальными

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct st_base {
    virtual void display() { cout << "st_base::display()" << endl; }
    //void display() { cout << "st_base::display()" << endl; }
};
 
struct st_der : st_base {
    void display() { cout << "st_der::display()" << endl; }
};
 
int main () {
 
    st_base* pointer = new st_der;
    
    pointer->display(); }
вывод
st_der::display()
если сделать функцию display не виртуальной, то при обращении к указателю на базовый st_base, инициализированный указателем на производный st_der, будет вызывать display из базового st_base
0
0 / 0 / 1
Регистрация: 01.11.2011
Сообщений: 26
19.09.2013, 15:39  [ТС] 6
Но мне не нужно переопределять эти два метода в производном классе, мне просто нужно их вызвать для производного класса и записать данные в него из ivan->SetName("...") и ivan->SetAge(...). Это можно как-то сделать используя унаследованные функции?

Цитата Сообщение от Cynacyn Посмотреть сообщение
В Вашем конкретном примере путаница вызвана тем, что в производном классе есть такие же данные члены, к которым в обращаетесь в information().
Имхо, дублирование данных лишнее, нужно просто убрать данные из производного класса и всё.
Если убрать данные для производного класса, то компилятор будет ругаться, что данные для базового класса являются скрытыми.
0
35 / 35 / 7
Регистрация: 02.05.2013
Сообщений: 109
19.09.2013, 17:52 7
Цитата Сообщение от qazc Посмотреть сообщение
Но мне не нужно переопределять эти два метода в производном классе, мне просто нужно их вызвать для производного класса и записать данные в него из ivan->SetName("...") и ivan->SetAge(...). Это можно как-то сделать используя унаследованные функции?



Если убрать данные для производного класса, то компилятор будет ругаться, что данные для базового класса являются скрытыми.
Ваши унаследованные функции работают с данными членами базового (наследуемого) класса.
Чтобы компилятор не ругался, нужно в классе human данные члены объявить в разделе protected
C++
1
2
3
   protected:
        string name;
        int age;
данные объявленные в этом разделе доступны производному классу, как если бы они были объявлены в разделе public, для остальных пользователей эти данные закрыты
1
35 / 35 / 7
Регистрация: 02.05.2013
Сообщений: 109
24.09.2013, 14:50 8
Цитата Сообщение от qazc Посмотреть сообщение
Доброго времени суток. Есть два вопроса:

2) В классе наследнике функция information() перегружается и в итоге имеем другой результат для класса наследника. В чем тогда отличие между таким способом изменения результата в наследнике и если бы функция information() была объявлена как virtual в классе human и в наследнике была бы переопределена?
Как я уже сказал, если бы инициализировали указатель на human (базовый) указателем на soldier (производный).
C++
1
2
human* p = new soldier;
p->information();
то при вызове метода information() (предполагается что он замещён в производном классе), вызывается метод soldier::information(), если в human метод information() объявлен как виртуальный, если нет - то тогда вызывается human::information().

+ ещё пример использования виртуальных функция из вики:
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
class A
{
public:
     virtual int function () {
        return 1;
     }
 
     int get() {
         return this->function();
     }
};
 
class B: public A
{
public:
     int function() {
        return 2;
     }
};
 
#include <iostream>
 
int main() {
   B b; 
 
   std::cout << b.get() << std::endl; // 2
 
   return 0;
}
rsdn: Зачем нужны виртуальные функции?

wiki: Виртуальные методы
1
0 / 0 / 1
Регистрация: 01.11.2011
Сообщений: 26
24.09.2013, 15:32  [ТС] 9
Спасибо
0
24.09.2013, 15:32
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.09.2013, 15:32
Помогаю со студенческими работами здесь

Наследование и виртуальные функции
Определить иерархию классов (игрушка, продукт, товар, молочный продукт). Определить в классе...

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

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

Наследование и виртуальные функции
#include &lt;iostream&gt; #include &lt;string&gt; #include &lt;cstring&gt; using namespace std; #include...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru