Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.67
ITcrusader
Эксперт C++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
#1

Обсудим наследование в C++? - C++

25.02.2013, 10:57. Просмотров 1428. Ответов 10
Метки нет (Все метки)

Приветы

Размышления о практической применимости и деталях различных вариаций наследования натолкнули на следующие вопросы.

1. Виртуальное наследование. Верно ли следующее суждение: единственная цель использования виртуального наследования - избежать неопределенности, возникающей в ромбовидных иерархиях? Гуглing на эту тему приводит меня к статьям/блогам/прочей ерунде, где авторы, будто сговорившись, будто раскрывая мне глаза, приводят однотипные примеры, касающиеся лишь этого момента.

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

P.S. Я, конеш, про в плюсах, но кроме ответов готов принять немного обоснованных насмешек от людей, обременённых большим опытом использования оного
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.02.2013, 10:57     Обсудим наследование в C++?
Посмотрите здесь:

C++ Наследование
Наследование в С++ C++
C++ Наследование
наследование C++
C++ Наследование
C++ Наследование
Наследование C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Kastaneda
Форумчанин
Эксперт С++
4468 / 2830 / 224
Регистрация: 12.12.2009
Сообщений: 7,199
Записей в блоге: 1
Завершенные тесты: 1
25.02.2013, 12:19     Обсудим наследование в C++? #2
1. да
2. порядок имеет значение.
Цитата Сообщение от ITcrusader Посмотреть сообщение
но, мне кажется, едва ли порядок этот сказывается на каких-то важных аспектах. Или я не прав здесь?
Если код пишет человек, который понимает, что он пишет, то проблем не будет, даже если он напутает порядок. Но в общем случае проблемы могут быть.
Простой пример (лень придумывать пример с наследованием) - не правильный порядок инициализации членов в конструкторе (a и b объявлены внутри класса в одном порядке, а инициализируются в другом)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
 
class A
{
public:
   int _a, _b;
   A(int aa) : _b(aa), _a(_b) {}
};
 
int main()
{
   A a(1);
   std::cout << a._a << std::endl;
}
ожидаемый вывод 1, но на разных компиляторах с разными ключами компиляции разный вывод, может 0, а может просто мусор.

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

Добавлено через 2 минуты

Не по теме:

Цитата Сообщение от Kastaneda Посмотреть сообщение
Если код пишет человек, который понимает, что он пишет
видел в README к GNU'шным тестам
"If you really understand C++ (and you know who you are) ... "

ITcrusader
Эксперт C++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
25.02.2013, 12:42  [ТС]     Обсудим наследование в C++? #3
Цитата Сообщение от Kastaneda Посмотреть сообщение
1. да
Славно) а то сидел, покоя не находил себе, думая, что чего-то не знаю еще)
Цитата Сообщение от Kastaneda Посмотреть сообщение
2. порядок имеет значение.
Ну да, для этого примера - верно (Мейерс в одном из советов писал). А вот с наследованием я чота голову поломал, раздумывая Походу, меня на собеседовании том нажгли)))

Цитата Сообщение от Kastaneda Посмотреть сообщение
"If you really understand C++ (and you know who you are) ... "
Ну вот я как раз создал тему, чтобы точно понимать, чего еще неизведанного (подводные камни) таит в себе это, как его многие называют, порождение больной фантазии (множественное наследование)
Kastaneda
Форумчанин
Эксперт С++
4468 / 2830 / 224
Регистрация: 12.12.2009
Сообщений: 7,199
Записей в блоге: 1
Завершенные тесты: 1
25.02.2013, 12:58     Обсудим наследование в C++? #4
Цитата Сообщение от ITcrusader Посмотреть сообщение
а то сидел, покоя не находил себе, думая, что чего-то не знаю еще)
ну не исключено, что я тоже чего-то незнаю
Но виртуальное наследование специально для ромбовидного и придумано, поэтому, думаю, врядли у него еще есть другое применение.
gray_fox
What a waste!
1256 / 1139 / 55
Регистрация: 21.04.2012
Сообщений: 2,361
Завершенные тесты: 3
25.02.2013, 14:35     Обсудим наследование в C++? #5
1. Так же позволяет избежать дублирования данных.
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
28.02.2013, 14:30     Обсудим наследование в C++? #6
Вот вам и зависимость:
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
#include <iostream>
 
class Base
{
};
 
class Derived1 : public virtual Base
{
public:
    Derived1(int x):
        m_x(x)
    {
    }
 
    int get_x() const
    {
        return m_x;
    }
    
private:
    int m_x;
};
 
class Derived2 : public virtual Base
{
public:
    Derived2(int x):
        m_x(x)
    {
    }
 
    int get_x() const
    {
        return m_x;
    }
    
private:
    int m_x;
};
 
class DoubleDerived : public Derived1, public Derived2
{
public:
    // Верный порядок
    DoubleDerived():
        Derived1(10),
        Derived2(Derived1::get_x())
    {
    }
    
    void print()
    {
        std::cout << Derived1::get_x() << "  " << Derived2::get_x() << std::endl;
    }
};
 
int main()
{
    DoubleDerived dd;
    
    dd.print();
    
    return 0;
}
Вывод: 10 10

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
#include <iostream>
 
class Base
{
};
 
class Derived1 : public virtual Base
{
public:
    Derived1(int x):
        m_x(x)
    {
    }
 
    int get_x() const
    {
        return m_x;
    }
    
private:
    int m_x;
};
 
class Derived2 : public virtual Base
{
public:
    Derived2(int x):
        m_x(x)
    {
    }
 
    int get_x() const
    {
        return m_x;
    }
    
private:
    int m_x;
};
 
class DoubleDerived : public Derived1, public Derived2
{
public:
    // Изменили порядок
    DoubleDerived():
        Derived2(10),
        Derived1(Derived2::get_x())
    {
    }
    
    void print()
    {
        std::cout << Derived1::get_x() << "  " << Derived2::get_x() << std::endl;
    }
};
 
int main()
{
    DoubleDerived dd;
    
    dd.print();
    
    return 0;
}
Вывод: 14254272 10

Компилятор: gcc version 4.4.3
ITcrusader
Эксперт C++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
28.02.2013, 14:53  [ТС]     Обсудим наследование в C++? #7
Воооооооо, по аналогии с инициализацией членов класса, тока зависимость от порядка следования в списке базовых классов.

По красафчику, спасиб - этого я не знал

И просьба, если знаешь, на что еще может влиять этот порядок, напиши, пожалуйста) Если более ничего нет - то и славно.
silent_1991
Эксперт С++
4956 / 3032 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
28.02.2013, 16:32     Обсудим наследование в C++? #8
Цитата Сообщение от ITcrusader Посмотреть сообщение
если знаешь, на что еще может влиять этот порядок, напиши, пожалуйста
Тут только одна полная аналогия с членами класса - от порядка их объявления зависит порядок вызова их конструкторов. Также и с базовыми классами - от порядка их "объявления" в списке родителей зависит порядок вызова их конструкторов. Больше ничего не вспоминается особенного. Правда, на работе Си да Джава только, плюсы уже забываются. Возможно, кто-то ещё что-то знает/помнит по этому поводу. Может быть, что-то изменилось/добавилось в последнем стандарте, у меня до него всё руки/глаза/мозг никак не дойдет (сколько слешей в одном посте, жуть ).
Kastaneda
28.02.2013, 17:34
  #9

Не по теме:

Цитата Сообщение от silent_1991 Посмотреть сообщение
сколько слешей в одном посте, жуть
жуть/жесть/ужас

ITcrusader
Эксперт C++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
06.03.2013, 22:27  [ТС]     Обсудим наследование в C++? #10
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Kastaneda, gray_fox, silent_1991, привет!
Случайно наткнулся на интересный способ применения виртуального наследования.

Используется для того, чтобы запретить наследование от какого-нибудь вашего класса. Вот листинг:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
template < class FinalClass > // сюда будет передаваться имя класса, от которого нельзя наследоваться
class LockInheritanceFrom   {
    friend FinalClass; // FriendClass'у необходим доступ к закрытому конструктору
    LockInheritanceFrom()   {   }
};
 
// объявляем класс, запрещая наследование от него (прикольно, что в код самого класса ничего не нужно вносить) :
class SomeClass: public virtual LockInheritanceFrom < SomeClass >
{
};
 
// пытаемся объявить наследника от нашего класса
class Derived: public SomeClass
{
};
 
int main()
{
    SomeClass obj;
    //Derived d; // ошибка компиляции при попытке создания объекта, наследующего от класса, от которого наследовать запретили
    return 0;
}
Вся фишка завязана на том, что конструктор самого базового виртуального класса может вызываться лишь листовым классом иерархии. А из-за того, что созданный нами Derived листовой, но конструктор базового класса - закрыт, использование класса Derived невозможно.

Раньше было бы, наверное полезно где-то использовать такой механизм. Но в нынешнем стандарте появился final))) Скорее бы новый стандарт нашел свое отражение в разных реализациях)))

Подумал, быть может вам будет интересно, код, вроде, только необходимое содержит
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.03.2013, 07:50     Обсудим наследование в C++?
Еще ссылки по теме:

C++ Наследование
Наследование C++
C++ Наследование
C++ Наследование
C++ Наследование

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

Или воспользуйтесь поиском по форуму:
Kastaneda
Форумчанин
Эксперт С++
4468 / 2830 / 224
Регистрация: 12.12.2009
Сообщений: 7,199
Записей в блоге: 1
Завершенные тесты: 1
07.03.2013, 07:50     Обсудим наследование в C++? #11
Ну да, интересное применение. Только вот это
C++
1
friend FinalClass;
С++11 extension.
gcc
Bash
1
error: non-class friend type 'FinalClass' is a C++11 extension [-Werror,-Wc++11-extensions]
Yandex
Объявления
07.03.2013, 07:50     Обсудим наследование в C++?
Ответ Создать тему
Опции темы

Текущее время: 14:01. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru