Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.97/37: Рейтинг темы: голосов - 37, средняя оценка - 4.97
 Аватар для irises
140 / 72 / 26
Регистрация: 29.06.2015
Сообщений: 186

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

31.07.2015, 23:58. Показов 10208. Ответов 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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
31.07.2015, 23:58
Ответы с готовыми решениями:

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

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

Как обратиться из конструктора базового абстрактного класса к свойству-массиву класса наследника
Добрый день. Подскажите как обратиться из конструктора базового абстрактного класса к свойству-массиву из класса наследника. Вроде бы...

131
 Аватар для smartpointer
70 / 64 / 40
Регистрация: 17.02.2014
Сообщений: 265
01.08.2015, 03:18
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Avazart Посмотреть сообщение
А откуда страсть нарушать инкапсуляцию?
В пределах protected не считаю нарушением, мы даем доступ не кому попало а только тому, кому нужно, и особо не заостряю внимание на правильности, только потому, что кто-то описал что так нельзя делать (на заборе тоже написано)
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 03:27
Цитата Сообщение от smartpointer Посмотреть сообщение
, мы даем доступ не кому попало а только тому, кому нужно
Вобщето кому попало, ибо- всем наследникам (если конечно вы не собираетесь их потом "скрывать", все 20 штук в каждом наследники "первого уровня")
... хорошо если их всего один уровень, а если больше?

Добавлено через 2 минуты
Цитата Сообщение от smartpointer Посмотреть сообщение
и особо не заостряю внимание на правильности, только потому, что кто-то описал что так нельзя делать (на заборе тоже написано)
В данном случае нет веских оснований что бы делать через protected.
0
 Аватар для smartpointer
70 / 64 / 40
Регистрация: 17.02.2014
Сообщений: 265
01.08.2015, 03:36
Цитата Сообщение от Avazart Посмотреть сообщение
Вобщето кому попало, ибо- всем наследникам (если конечно вы не собираетесь их потом "скрывать", все 20 штук в каждом наследники "первого уровня")
... хорошо если их всего один уровень, а если больше?
Вы считаете это косяк программиста или недоработка языка ?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 03:57
Цитата Сообщение от smartpointer Посмотреть сообщение
Вы считаете это косяк программиста или недоработка языка ?
А вы как думаете зачем правила?

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
class A
{
   public:
      virtual int value()const{ return v_; };
   protected:
       int v_;
};
 
class B: public A  // *1000
{
   public:
      virtual int value()const{ return v_*1000; };
};
 
 
class C: public B  // еще раз на 1000
{
   public:
     virtual int value()const{ return v_*1000; }; /* Упс, это то что нам надо?!!! */
     //  или возможно хотели это:
     //  virtual  int value()const{ return B::value()*1000; }; 
     //  Логика: 
     //      мы наследуем поведения А или все же B?
};
Добавлено через 16 минут
Ну и с закрытием как вариант с разруливание проблемы

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
class A
{
   public:
      virtual int value()const{ return v_; };
   protected:
       int v_;
};
 
class B: public A  // *1000
{
   public:
      virtual int value()const{ return v_*1000; };
   private:
      using A::v_; /*Решение?  Или все же может лучше сразу сеттеры/геттеры? */
};
 
class C: public B  // еще раз на 1000
{
   public:
     // virtual int value()const{ return v_*1000; }; /* Не позволено! v_  закрыт */
     //  или возможно хотели это:
     virtual  int value()const{ return B::value()*1000; }; 
     //  Логика: 
     //      мы наследуем поведения А или все же B?
};
3
 Аватар для Eraston
60 / 11 / 4
Регистрация: 09.09.2014
Сообщений: 182
01.08.2015, 04:59

Не по теме:

Цитата Сообщение от Avazart Посмотреть сообщение
А откуда страсть нарушать инкапсуляцию мотивируя расходом памяти?
Очень смахивает на сектантскую фразу ;D



Добавлено через 27 минут
Цитата Сообщение от Avazart Посмотреть сообщение
или возможно хотели это:
* * *// *virtual *int value()const{ return B::value()*1000; };
* * *// *Логика:
* * *// * * *мы наследуем поведения А или все же B?
Неужели. Протрезвили. Если я правильно понимаю, при наследовании не-private-члена он создается в экзмепляре в количестве равном количеству наследований + 1 ( base > s1 > s2 - в s2 будет 3 экземпляра свойства X, что прямо противоречит не правилам инкапсуляции, а законам мироздания ). А private-члены создаются в единственном экземпляре в суперклассе. Чего нельзя сказать о методах ( если свойство одно, то методов работы с ним множество ), что обуславливает возможность сохранения их со всех предков и желаемый доступ, либо внутри класса, либо открытый, либо закрыть для следующих наследников ( типа устаревший для современности ). Если так, то с этого надо было начинать, а то: "инкапсуляция, инкапсуляция..."
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.08.2015, 05:23
Цитата Сообщение от 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
60 / 11 / 4
Регистрация: 09.09.2014
Сообщений: 182
01.08.2015, 05:24
Собственно, теперь понял, почему размер классов у меня рос с прогрессией 16 48 104, вместо 16 40 64.
Avazart, спасибо за терпение, обсуждение и примеры.
0
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
01.08.2015, 06:39
Цитата Сообщение от hoggy Посмотреть сообщение
делать сеттер в этой ситуации не имеет смысла.
потому что весь дизайн уже задал std::function.
и сеттеру тупо нечем было бы заниматься.
в принципе.
Не знаю, здесь мне кажется более феншуйным передавать указатель на функцию как аргумент либо конструктору кнопки, либо функции SimulateClick.
0
 Аватар для smartpointer
70 / 64 / 40
Регистрация: 17.02.2014
Сообщений: 265
01.08.2015, 06:59
Цитата Сообщение от 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
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
01.08.2015, 07:02
Цитата Сообщение от irises Посмотреть сообщение
этот класс будет управлять сетью заправок, с помощью методов, которые показала выше - буду добавлять новые заправки
и вот через этот главный класс хочу организовать заправку машин и подачу бензина на заправку (тоесть уход и приход бензина) через абстрактный класс
Вообще-то проектировать надо начинать с интерфейсных функций, а не с данных. А зачем вам абстрактная заправка понадобилась? Это в задании так или вы сами придумали?
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.08.2015, 07:48
Цитата Сообщение от Mr.X Посмотреть сообщение
Не знаю, здесь мне кажется более феншуйным передавать указатель на функцию как аргумент либо конструктору кнопки
лепить громоздкий вариадик-конструктор,
который на самом деле тупо делегирует все std::function?

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

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

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

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

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

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

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

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

но никто в здравом уме не делает кастомизацию в конструкторах.
0
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
01.08.2015, 10:20
Цитата Сообщение от hoggy Посмотреть сообщение
лепить
Цитата Сообщение от hoggy Посмотреть сообщение
ну ок. слепили
Цитата Сообщение от hoggy Посмотреть сообщение
но никто в здравом уме не делает
Ну вот сразу видно благородного и воспитанного джентльмена! Охотно бы поспорил, но в моем лексиконе просто нет столь же изысканных выражений.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 11:17
hoggy, Ну впринципе да всегда могут быть исключения, стоит смотреть по месту, но мне кажется все же стоит думать о том как спрятать - Signals2
Ибо открытым мы делает все же объект, в том время как в нем может быть больше возможностей чем нам хотелось бы показать.

Что касается исключения- паттерн property
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.08.2015, 11:28
Цитата Сообщение от Avazart Посмотреть сообщение
но мне кажется все же стоит думать о том как спрятать
плохой путь.
именно это я и называю "громоздкой вариадик шаблоно-функцией"
и начинается:
1. под методы
2. под свободные функи.
3. под функторы.

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

нафига?

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

решение уже является законченным дизайном.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 11:37
Цитата Сообщение от hoggy Посмотреть сообщение
решение уже является законченным дизайном.
Ну в std::function есть оператор вызова, вполне может оказаться что мы бы не хотели что бы пользователь имел возможность использовать его напряму менуя метод. Кстати как быть с наследованием на примере иерархии A/B/C если открывать std::function?

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

Добавлено через 5 минут
В boost::signals2 куда больше возможностей и не все охота их показывать/допускать.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.08.2015, 11:47
Цитата Сообщение от Avazart Посмотреть сообщение
не хотели что бы пользователь имел возможность использовать его напряму менуя метод.
ну если так, тогда выбора не остается - придется прятать в приватах.

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

выглядит не очень читабельно,
но это уже на совести пользователя.
если что нибудь пойдет не так,
std::function сам отобьется (бросит исключение, etc).
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 12:10
Цитата Сообщение от 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
60 / 11 / 4
Регистрация: 09.09.2014
Сообщений: 182
01.08.2015, 12:25
Цитата Сообщение от smartpointer Посмотреть сообщение
Что видим - адреса одинаковые, следовательно никаких копий - это собственность A, и никакого роста памяти!
Не знаю, у меня при наследовании классы росли не соотвествующе увеличению количества переменных - больше.

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

Цитата Сообщение от Avazart Посмотреть сообщение
инкапсуляцию
В таком случае еще более острым становится вопрос, объявленный в этой теме, поскольку она не только не объединяет данные, а скорее разъединяет их с таким уровнем доступа, что не есть гуд.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 13:18
Цитата Сообщение от Eraston Посмотреть сообщение
поскольку она не только не объединяет данные,
Объединяет логически связанные данные, из чего очевидно:
Цитата Сообщение от Eraston Посмотреть сообщение
, а скорее разъединяет
Что не связано...
Увидел треш с #pragma pack(push, 4) в классах не стал читать.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
01.08.2015, 14:18
Цитата Сообщение от 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.08.2015, 14:18

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

Метод абстрактного класса не видит переменные дочернего класса
есть abstract class A{ protected static $dir; public static function f(){} } и два класса B,C наследника { protected static...

Вызов функции класса, который наследуется от абстрактного класса
Предположим, что существует класс Base, который является абстрактным class Base{ public: virtual void something() = 0; virtual...

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

Как обратится к объекту класса
Не могу обратится к объекту класса по индексу int main() { setlocale(LC_ALL, &quot;RUS&quot;); system(&quot;cls&quot;); ...


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

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
Doom для терминала без стрельбы и монстров. 3D Raycasting на ascii.
dcc0 05.07.2026
Попросил нейронную сеть deepai. org написать рейкастинг 3D с библиотекой ncurses для Linux. Чтобы можно было ходить на стрелочки. Чтобы стены были отрисованы символами. Справилась. Первый вариант. . .
Установка статуса документа по условию
Maks 05.07.2026
Алгоритм из решения ниже реализован на нетиповом документе "НарядПутевка" разработанного в КА2. Задача: в табличной части "Материалы" документа при записи автоматически устанавливать статус. . .
Сезонность и суточность закисления почв
anaschu 04.07.2026
200 часов это все равно моловато. Есть ситуации, но нестандартные, когда смена происходит за 5 лет. Но обычно это 50 лет и более. Наверное, закисление почвы происходит сезонно в средней. . .
В чем ценность человеческого опыта в глобальном смысле?
kumehtar 03.07.2026
Возможно, ценность человека не в том, что он однажды достигает мудрости, а в том, что он становится носителем карты пути. Он знает не только истину, но и последовательность внутренних изменений,. . .
интеграция AnyLogic с самописным REST API и переход на Odoo
anaschu 03.07.2026
Успешная интеграция AnyLogic с самописным REST API и переход на промышленную Odoo WMS Сегодня проделал огромный путь от простой симуляции физических процессов до построения полноценной. . .
Поиск всех путей на ориентированном графе. Linux
dcc0 02.07.2026
Переработка старого кода из моей статьи. Через несколько переработок от PHP кода к C89 (надеюсь, 89). Но довольно запутанно получилось. Код для Linux. Но если убрать time и то, что с ним. . .
Сам себя обучал rest api
anaschu 02.07.2026
Педагогический лайфхак: Почему чистый REST API для ученика намного круче, чем готовые библиотеки Когда мы отказались от капризного JAR-файла AnyLogic и переписали код на стандартный HttpClient,. . .
rest api anylogic - выполнение модели на своём русском сайте
anaschu 02.07.2026
Как подружиться с AnyLogic Cloud API, победить провайдеров и развернуться Java-бэкенд в Docker на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru