Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.72
irises
84 / 41 / 9
Регистрация: 29.06.2015
Сообщений: 126
Завершенные тесты: 1
#1

Как обратится к обьекту класса, являющегося наследником абстрактного класса - C++

31.07.2015, 23:58. Просмотров 2922. Ответов 131
Метки нет (Все метки)

Здравствуйте!
У меня есть 4 класса: один виртуальный, следующие 2 - наследуют виртуальный класс и последний класс содержит
указатель на виртуальный класс (динамический массив, который растет от методов buildCar и buildTruck).
eFuel - это также класс, который содержит еще класс, но в данном вопросе они не принимают участия.
Вопрос: как через указатель четвертого класса доступится к наследующим классам?
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
class aGasStation
{
    friend class bCar;
    friend class cTruck;
protected :
    double A92;
    double A95;
    double A98;
    int cistern92;
    int cistern95;
    int cistern98;
public:
    aGasStation ();
    ~aGasStation ();
    virtual void print () = 0;
};
 
class bCar : public aGasStation
{
    eFuel fuelcar;
public:
    bCar ();
    ~bCar ();
    void print ();
};
 
class cTruck  : public aGasStation
{
    eFuel fueltruck;
public:
    cTruck ();
    ~cTruck ();
    void print ();
};
 
class dChainOfGasStation
{
    aGasStation *base;
    double money;
    static int size;
public:
    dChainOfGasStation ();
    ~dChainOfGasStation ();
    friend void buildCar (dChainOfGasStation *tmp);
    friend void buildTruck (dChainOfGasStation *tmp);
};
C++
1
2
3
4
5
6
7
8
void main ()
{
    dChainOfGasStation base;
    buildCar (&base);
    buildCar (&base);
    buildTruck (&base);
    buildCar (&base);   
}
Пытаюсь таким способом в main(), но знаю что base[0] - это private, а сделать его public противоречит правилам С++
C++
1
base.base[0]->print();
Можно написать set-метод, но каким образом это сделать я не знаю.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.07.2015, 23:58
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как обратится к обьекту класса, являющегося наследником абстрактного класса (C++):

как узнать,является данный объект класса А1 наследником класса А2 - C++
Всем привет)есть классы S, A1, A2, B1, B2. Иерархия наследования следующая S - Является родителем для всех классов и он имеет...

Как полю класса А обратится к приватной функции класса А? - C++
Есть лифт (класс "Elevator "), в котором находится кнопка (класс "Button"). При нажатии на кнопку (функция "push") должен пойти сигнал в...

Поместить в динамически расширяемый массив объекты класса, производные от базового абстрактного класса - C++
Помогите пожалуйста новичку! (мне). Я хочу создать динамически расширяющийся массив указателей на базовый абстрактный класс,...

Как инициализировать члены класса, являющегося параметром шаблона - C++
#include <iostream> #include <conio.h> using namespace std; template <typename SomeClass> class Array { private : ...

Как организовать интерфейс в виде абстрактного класса? - C++
У меня есть задание, вот его часть: - расчёты движения предмета должны осуществляться в библиотеке, для которой нужно создать интерфейс...

Использование конструктора базового класса наследником - C++
Доброго дня, коллеги! Решал одну задачку и столкнулся с проблемой. По условию дан класс String, моделирующий работу типа данных string....

131
hoggy
6800 / 2986 / 514
Регистрация: 15.11.2014
Сообщений: 6,754
Завершенные тесты: 1
01.08.2015, 05:23 #46
Цитата Сообщение от Eraston Посмотреть сообщение
Очень смахивает на сектантскую фразу
Avazart - прав.
всем остальным - читать Макконелла.

если Макконелл не поможет - уже ничто не поможет.

зы:

Avazart,
в отдельных случаях данные члены могут быть открытыми/защищенными.
это случаи, когда они логически являются частью интерфейса,
а не данными.

то есть, они отвечают за управление классом (подобно публичным методам),
а не за состояние его экземпляра.

пример:

допустим, есть кнопка (библиотечный класс),
и нужно посетить реакцию на клик:

http://rextester.com/GBPX73313

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
#include <iostream>
#include <functional>
 
 
struct Button
{
    typedef std::function<void()>
        Event;
    
    
    Event eventClick;
    
    void SimulateClick()
    {
        if(eventClick)
            eventClick();
    }
 
};
 
 
void OnClick()
{
    std::cout<<"button was click\n";
 
}
 
int main()
{
    std::cout << "Hello, world!\n";
    
    Button bt;
    
    bt.eventClick = OnClick;
    
    bt.SimulateClick();
}
делать сеттер в этой ситуации не имеет смысла.
потому что весь дизайн уже задал std::function.
и сеттеру тупо нечем было бы заниматься.
в принципе.
0
Eraston
53 / 10 / 2
Регистрация: 09.09.2014
Сообщений: 127
01.08.2015, 05:24 #47
Собственно, теперь понял, почему размер классов у меня рос с прогрессией 16 48 104, вместо 16 40 64.
Avazart, спасибо за терпение, обсуждение и примеры.
0
Mr.X
Эксперт С++
3054 / 1699 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
01.08.2015, 06:39 #48
Цитата Сообщение от hoggy Посмотреть сообщение
делать сеттер в этой ситуации не имеет смысла.
потому что весь дизайн уже задал std::function.
и сеттеру тупо нечем было бы заниматься.
в принципе.
Не знаю, здесь мне кажется более феншуйным передавать указатель на функцию как аргумент либо конструктору кнопки, либо функции SimulateClick.
0
smartpointer
69 / 63 / 24
Регистрация: 17.02.2014
Сообщений: 264
01.08.2015, 06:59 #49
Цитата Сообщение от Avazart Посмотреть сообщение
мы наследуем поведения А или все же B?
Конструктор специально убрали. В объявлении C явно указано public B - а следовательно, переопределяя дефолтный конструктор мы можем явно вызвать только конструктор B. Класс C еще ничего не знает про A, точнее знает поскольку декларация уже произошла, но не знает что это дедушка для него, выясняется это только, когда конструктор B вызвал конструктор A,а C вызвал B. Все тоже самое происходит даже если мы не определяли конструктор, ибо подставится компилятором.В итоге класс C увидит у класса B все, что у него там унаследовано от отца.
Теперь развиваем магию над int v_ в C заносим (только первый вариант кода).
C++
1
2
3
4
5
6
void Print()
{
    std::cout<< &(A::v_) << std::endl;
    std::cout<< &(B::v_) << std::endl;
    std::cout<< &(C::v_) << std::endl;
}
Что видим - адреса одинаковые, следовательно никаких копий - это собственность A, и никакого роста памяти! Но кстати за using спасибо, первый раз вижу такой хак
0
Mr.X
Эксперт С++
3054 / 1699 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
01.08.2015, 07:02 #50
Цитата Сообщение от irises Посмотреть сообщение
этот класс будет управлять сетью заправок, с помощью методов, которые показала выше - буду добавлять новые заправки
и вот через этот главный класс хочу организовать заправку машин и подачу бензина на заправку (тоесть уход и приход бензина) через абстрактный класс
Вообще-то проектировать надо начинать с интерфейсных функций, а не с данных. А зачем вам абстрактная заправка понадобилась? Это в задании так или вы сами придумали?
1
hoggy
6800 / 2986 / 514
Регистрация: 15.11.2014
Сообщений: 6,754
Завершенные тесты: 1
01.08.2015, 07:48 #51
Цитата Сообщение от Mr.X Посмотреть сообщение
Не знаю, здесь мне кажется более феншуйным передавать указатель на функцию как аргумент либо конструктору кнопки
лепить громоздкий вариадик-конструктор,
который на самом деле тупо делегирует все std::function?

на крайняк конструктор может принимать std::function,
а не указатель-на-функцию.
это позволит избежать шаблоно-кода,
и не придется ограничивать функционал только лишь указатель-на-функцию.

ну ок. слепили.

и тут проблема:
у кнопки может быть до чертиков разных событий:
CLICK, DCLICK, PASSED,HOVER,OUT - это лишь джентельменский набор.

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

и что осталось от вашего феншуя?

--------------

по феншую конструктор должен принимать только и только самый минимум настроек,
минимально необходимый для сохранения работоспособности.

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

но никто в здравом уме не делает кастомизацию в конструкторах.
0
Mr.X
Эксперт С++
3054 / 1699 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
01.08.2015, 10:20 #52
Цитата Сообщение от hoggy Посмотреть сообщение
лепить
Цитата Сообщение от hoggy Посмотреть сообщение
ну ок. слепили
Цитата Сообщение от hoggy Посмотреть сообщение
но никто в здравом уме не делает
Ну вот сразу видно благородного и воспитанного джентльмена! Охотно бы поспорил, но в моем лексиконе просто нет столь же изысканных выражений.
0
Avazart
Эксперт С++
7420 / 5510 / 316
Регистрация: 10.12.2010
Сообщений: 24,597
Записей в блоге: 17
01.08.2015, 11:17 #53
hoggy, Ну впринципе да всегда могут быть исключения, стоит смотреть по месту, но мне кажется все же стоит думать о том как спрятать - Signals2
Ибо открытым мы делает все же объект, в том время как в нем может быть больше возможностей чем нам хотелось бы показать.

Что касается исключения- паттерн property
0
hoggy
6800 / 2986 / 514
Регистрация: 15.11.2014
Сообщений: 6,754
Завершенные тесты: 1
01.08.2015, 11:28 #54
Цитата Сообщение от Avazart Посмотреть сообщение
но мне кажется все же стоит думать о том как спрятать
плохой путь.
именно это я и называю "громоздкой вариадик шаблоно-функцией"
и начинается:
1. под методы
2. под свободные функи.
3. под функторы.

велосипедирование функционала std::function.

нафига?

учитывая, что:
Цитата Сообщение от Avazart Посмотреть сообщение
в нем может быть больше возможностей чем нам хотелось бы показать.
нечего добавить.
нечего убавить.

решение уже является законченным дизайном.
0
Avazart
Эксперт С++
7420 / 5510 / 316
Регистрация: 10.12.2010
Сообщений: 24,597
Записей в блоге: 17
01.08.2015, 11:37 #55
Цитата Сообщение от hoggy Посмотреть сообщение
решение уже является законченным дизайном.
Ну в std::function есть оператор вызова, вполне может оказаться что мы бы не хотели что бы пользователь имел возможность использовать его напряму менуя метод. Кстати как быть с наследованием на примере иерархии A/B/C если открывать std::function?

C++
1
bt.eventClick();// вместо bt.SimulateClick()
Естетственно это "натянуто", но я как понял мы говорим в общем и не только о std::function

Добавлено через 5 минут
В boost::signals2 куда больше возможностей и не все охота их показывать/допускать.
0
hoggy
6800 / 2986 / 514
Регистрация: 15.11.2014
Сообщений: 6,754
Завершенные тесты: 1
01.08.2015, 11:47 #56
Цитата Сообщение от Avazart Посмотреть сообщение
не хотели что бы пользователь имел возможность использовать его напряму менуя метод.
ну если так, тогда выбора не остается - придется прятать в приватах.

хотя хз, зачем такое запрещать.
это ж батону никак навредить не может.

выглядит не очень читабельно,
но это уже на совести пользователя.
если что нибудь пойдет не так,
std::function сам отобьется (бросит исключение, etc).
0
Avazart
Эксперт С++
7420 / 5510 / 316
Регистрация: 10.12.2010
Сообщений: 24,597
Записей в блоге: 17
01.08.2015, 12:10 #57
Цитата Сообщение от smartpointer Посмотреть сообщение
A, и никакого роста памяти!
Это рост памяти? Ну ну продолжайте экономить на спичках...

Цитата Сообщение от smartpointer Посмотреть сообщение
Конструктор специально убрали. В объявлении C явно указано public B - а следовательно, переопределяя дефолтный конструктор мы можем явно вызвать только конструктор B.
Чет не понял зачем там конструктор. Вообще не понял про конструктор.
Цитата Сообщение от smartpointer Посмотреть сообщение
В итоге класс C увидит у класса B все, что у него там унаследовано от отца.
Спасибо кеп, я вообщето и показал что он видит то что ему не нужно видеть что черевато ошибками.

Добавлено через 4 минуты
Цитата Сообщение от hoggy Посмотреть сообщение
хотя хз, зачем такое запрещать.
Ну это да. Я говорил в общем, да и как бы лигчески правильно скрывать все что не нужно пользователю, что бы исключить к максимуму возможность неправильного использования класса пользователем.

Добавлено через 16 минут
Цитата Сообщение от Mr.X Посмотреть сообщение
указатель на функцию как аргумент либо конструктору кнопки, либо функции SimulateClick.
Ну SimulateClick может и вообще не быть, т.е вызов может происходить при получении сообщения от системы.
Конструктор- будет жестко задавать "обработчик" нельзя будет его менять в рантайме.

P.S.: std::function кстати подходит не лучшим способом ибо не исключает вероятности что будет ссылаться на удаленный объект, поэтому я и упамянул boost::signals2.
0
Eraston
53 / 10 / 2
Регистрация: 09.09.2014
Сообщений: 127
01.08.2015, 12:25 #58
Цитата Сообщение от smartpointer Посмотреть сообщение
Что видим - адреса одинаковые, следовательно никаких копий - это собственность A, и никакого роста памяти!
Не знаю, у меня при наследовании классы росли не соотвествующе увеличению количества переменных - больше.

Цитата Сообщение от Avazart Посмотреть сообщение
Это рост памяти? Ну ну продолжайте экономить на спичках...
Это смотря как посмотреть. Наша планета тоже спичка в Галактике, но и в этой спичке море интересного. Грамотный программист найдет оптимальный режим между объемом занимаемой памяти и нагрузкой на процессор (то и не удивительно, что "калькулятор", вдруг оказывается, затребляет по 500 Мб ОЗУ непонятно зачем)

Цитата Сообщение от Avazart Посмотреть сообщение
инкапсуляцию
В таком случае еще более острым становится вопрос, объявленный в этой теме, поскольку она не только не объединяет данные, а скорее разъединяет их с таким уровнем доступа, что не есть гуд.
0
Avazart
Эксперт С++
7420 / 5510 / 316
Регистрация: 10.12.2010
Сообщений: 24,597
Записей в блоге: 17
01.08.2015, 13:18 #59
Цитата Сообщение от Eraston Посмотреть сообщение
поскольку она не только не объединяет данные,
Объединяет логически связанные данные, из чего очевидно:
Цитата Сообщение от Eraston Посмотреть сообщение
, а скорее разъединяет
Что не связано...
Увидел треш с #pragma pack(push, 4) в классах не стал читать.
0
DrOffset
7506 / 4502 / 1023
Регистрация: 30.01.2014
Сообщений: 7,362
01.08.2015, 14:18 #60
Цитата Сообщение от Avazart Посмотреть сообщение
А что расказывать friend нарушает инкапсуляцию
Со всем согласен, кроме этого. Нарушает инкапсуляцию не friend, а программист, который неправильно его использует.
Собственно, об этом Страуструп высказывался довольно четко:
I have never been able to see the recurring assertions that a friend declaration "violates encapsulation" as anything but a combination of ignorance and confusion with non-C++ terminology.
0
01.08.2015, 14:18
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.08.2015, 14:18
Привет! Вот еще темы с ответами:

Запрет shared_ptr быть наследником определённого класса - C++
Добрый день, #include &lt;memory&gt; class A { }; class B : public A {

Как при помощи указателя на базовый класс обратится к полю наследуемого класса? - C++
Всем привет! столкнулся с такой проблемой. У меня есть массив указателей на базовый виртуальный класс,и например я присваиваю указателю на...

как исправить Ошибка 8 error C2259: Tabl: невозможно создать экземпляр абстрактного класса - C++
имеется абстрактный класс, у нее есть 4 виртуальных функций: запись и чтение с помощью С и С++ имеется класс Tabl производный от...

Создание объекта класса, являющегося суммой 2ух других - C++
Нужно получить время на часах, сложив 2 другие временные отметки. Как я понимаю, нужно переопределить операцию сложения. Тогда как будет...


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

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

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