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

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.72
irises
 Аватар для irises
68 / 25 / 8
Регистрация: 29.06.2015
Сообщений: 101
31.07.2015, 23:58     Как обратится к обьекту класса, являющегося наследником абстрактного класса #1
Здравствуйте!
У меня есть 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-метод, но каким образом это сделать я не знаю.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
31.07.2015, 23:58     Как обратится к обьекту класса, являющегося наследником абстрактного класса
Посмотрите здесь:

Реализация абстрактного класса C++
как исправить Ошибка 8 error C2259: Tabl: невозможно создать экземпляр абстрактного класса C++
Создание объекта класса, являющегося суммой 2ух других C++
как узнать,является данный объект класса А1 наследником класса А2 C++
C++ Как организовать интерфейс в виде абстрактного класса?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
smartpointer
 Аватар для smartpointer
64 / 58 / 23
Регистрация: 17.02.2014
Сообщений: 250
01.08.2015, 03:18     Как обратится к обьекту класса, являющегося наследником абстрактного класса #41
Цитата Сообщение от Avazart Посмотреть сообщение
А откуда страсть нарушать инкапсуляцию?
В пределах protected не считаю нарушением, мы даем доступ не кому попало а только тому, кому нужно, и особо не заостряю внимание на правильности, только потому, что кто-то описал что так нельзя делать (на заборе тоже написано)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 17
01.08.2015, 03:27     Как обратится к обьекту класса, являющегося наследником абстрактного класса #42
Цитата Сообщение от smartpointer Посмотреть сообщение
, мы даем доступ не кому попало а только тому, кому нужно
Вобщето кому попало, ибо- всем наследникам (если конечно вы не собираетесь их потом "скрывать", все 20 штук в каждом наследники "первого уровня")
... хорошо если их всего один уровень, а если больше?

Добавлено через 2 минуты
Цитата Сообщение от smartpointer Посмотреть сообщение
и особо не заостряю внимание на правильности, только потому, что кто-то описал что так нельзя делать (на заборе тоже написано)
В данном случае нет веских оснований что бы делать через protected.
smartpointer
 Аватар для smartpointer
64 / 58 / 23
Регистрация: 17.02.2014
Сообщений: 250
01.08.2015, 03:36     Как обратится к обьекту класса, являющегося наследником абстрактного класса #43
Цитата Сообщение от Avazart Посмотреть сообщение
Вобщето кому попало, ибо- всем наследникам (если конечно вы не собираетесь их потом "скрывать", все 20 штук в каждом наследники "первого уровня")
... хорошо если их всего один уровень, а если больше?
Вы считаете это косяк программиста или недоработка языка ?
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 17
01.08.2015, 03:57     Как обратится к обьекту класса, являющегося наследником абстрактного класса #44
Цитата Сообщение от 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?
};
Eraston
 Аватар для Eraston
53 / 10 / 2
Регистрация: 09.09.2014
Сообщений: 123
01.08.2015, 04:59     Как обратится к обьекту класса, являющегося наследником абстрактного класса #45

Не по теме:

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



Добавлено через 27 минут
Цитата Сообщение от Avazart Посмотреть сообщение
или возможно хотели это:
* * *// *virtual *int value()const{ return B::value()*1000; };
* * *// *Логика:
* * *// * * *мы наследуем поведения А или все же B?
Неужели. Протрезвили. Если я правильно понимаю, при наследовании не-private-члена он создается в экзмепляре в количестве равном количеству наследований + 1 ( base > s1 > s2 - в s2 будет 3 экземпляра свойства X, что прямо противоречит не правилам инкапсуляции, а законам мироздания ). А private-члены создаются в единственном экземпляре в суперклассе. Чего нельзя сказать о методах ( если свойство одно, то методов работы с ним множество ), что обуславливает возможность сохранения их со всех предков и желаемый доступ, либо внутри класса, либо открытый, либо закрыть для следующих наследников ( типа устаревший для современности ). Если так, то с этого надо было начинать, а то: "инкапсуляция, инкапсуляция..."
hoggy
5229 / 2120 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 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.
и сеттеру тупо нечем было бы заниматься.
в принципе.
Eraston
 Аватар для Eraston
53 / 10 / 2
Регистрация: 09.09.2014
Сообщений: 123
01.08.2015, 05:24     Как обратится к обьекту класса, являющегося наследником абстрактного класса #47
Собственно, теперь понял, почему размер классов у меня рос с прогрессией 16 48 104, вместо 16 40 64.
Avazart, спасибо за терпение, обсуждение и примеры.
Mr.X
Эксперт С++
 Аватар для Mr.X
2803 / 1579 / 247
Регистрация: 03.05.2010
Сообщений: 3,672
01.08.2015, 06:39     Как обратится к обьекту класса, являющегося наследником абстрактного класса #48
Цитата Сообщение от hoggy Посмотреть сообщение
делать сеттер в этой ситуации не имеет смысла.
потому что весь дизайн уже задал std::function.
и сеттеру тупо нечем было бы заниматься.
в принципе.
Не знаю, здесь мне кажется более феншуйным передавать указатель на функцию как аргумент либо конструктору кнопки, либо функции SimulateClick.
smartpointer
 Аватар для smartpointer
64 / 58 / 23
Регистрация: 17.02.2014
Сообщений: 250
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 спасибо, первый раз вижу такой хак
Mr.X
Эксперт С++
 Аватар для Mr.X
2803 / 1579 / 247
Регистрация: 03.05.2010
Сообщений: 3,672
01.08.2015, 07:02     Как обратится к обьекту класса, являющегося наследником абстрактного класса #50
Цитата Сообщение от irises Посмотреть сообщение
этот класс будет управлять сетью заправок, с помощью методов, которые показала выше - буду добавлять новые заправки
и вот через этот главный класс хочу организовать заправку машин и подачу бензина на заправку (тоесть уход и приход бензина) через абстрактный класс
Вообще-то проектировать надо начинать с интерфейсных функций, а не с данных. А зачем вам абстрактная заправка понадобилась? Это в задании так или вы сами придумали?
hoggy
5229 / 2120 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
01.08.2015, 07:48     Как обратится к обьекту класса, являющегося наследником абстрактного класса #51
Цитата Сообщение от Mr.X Посмотреть сообщение
Не знаю, здесь мне кажется более феншуйным передавать указатель на функцию как аргумент либо конструктору кнопки
лепить громоздкий вариадик-конструктор,
который на самом деле тупо делегирует все std::function?

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

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

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

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

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

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

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

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

но никто в здравом уме не делает кастомизацию в конструкторах.
Mr.X
Эксперт С++
 Аватар для Mr.X
2803 / 1579 / 247
Регистрация: 03.05.2010
Сообщений: 3,672
01.08.2015, 10:20     Как обратится к обьекту класса, являющегося наследником абстрактного класса #52
Цитата Сообщение от hoggy Посмотреть сообщение
лепить
Цитата Сообщение от hoggy Посмотреть сообщение
ну ок. слепили
Цитата Сообщение от hoggy Посмотреть сообщение
но никто в здравом уме не делает
Ну вот сразу видно благородного и воспитанного джентльмена! Охотно бы поспорил, но в моем лексиконе просто нет столь же изысканных выражений.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 17
01.08.2015, 11:17     Как обратится к обьекту класса, являющегося наследником абстрактного класса #53
hoggy, Ну впринципе да всегда могут быть исключения, стоит смотреть по месту, но мне кажется все же стоит думать о том как спрятать - Signals2
Ибо открытым мы делает все же объект, в том время как в нем может быть больше возможностей чем нам хотелось бы показать.

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

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

нафига?

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

решение уже является законченным дизайном.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 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 куда больше возможностей и не все охота их показывать/допускать.
hoggy
5229 / 2120 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
01.08.2015, 11:47     Как обратится к обьекту класса, являющегося наследником абстрактного класса #56
Цитата Сообщение от Avazart Посмотреть сообщение
не хотели что бы пользователь имел возможность использовать его напряму менуя метод.
ну если так, тогда выбора не остается - придется прятать в приватах.

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

выглядит не очень читабельно,
но это уже на совести пользователя.
если что нибудь пойдет не так,
std::function сам отобьется (бросит исключение, etc).
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 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.
Eraston
 Аватар для Eraston
53 / 10 / 2
Регистрация: 09.09.2014
Сообщений: 123
01.08.2015, 12:25     Как обратится к обьекту класса, являющегося наследником абстрактного класса #58
Цитата Сообщение от smartpointer Посмотреть сообщение
Что видим - адреса одинаковые, следовательно никаких копий - это собственность A, и никакого роста памяти!
Не знаю, у меня при наследовании классы росли не соотвествующе увеличению количества переменных - больше.

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

Цитата Сообщение от Avazart Посмотреть сообщение
инкапсуляцию
В таком случае еще более острым становится вопрос, объявленный в этой теме, поскольку она не только не объединяет данные, а скорее разъединяет их с таким уровнем доступа, что не есть гуд.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 17
01.08.2015, 13:18     Как обратится к обьекту класса, являющегося наследником абстрактного класса #59
Цитата Сообщение от Eraston Посмотреть сообщение
поскольку она не только не объединяет данные,
Объединяет логически связанные данные, из чего очевидно:
Цитата Сообщение от Eraston Посмотреть сообщение
, а скорее разъединяет
Что не связано...
Увидел треш с #pragma pack(push, 4) в классах не стал читать.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.08.2015, 14:18     Как обратится к обьекту класса, являющегося наследником абстрактного класса
Еще ссылки по теме:

Как при помощи указателя на базовый класс обратится к полю наследуемого класса? C++
C++ Использование абстрактного класса
C++ Как полю класса А обратится к приватной функции класса А?

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

Или воспользуйтесь поиском по форуму:
DrOffset
6458 / 3832 / 885
Регистрация: 30.01.2014
Сообщений: 6,627
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.
Yandex
Объявления
01.08.2015, 14:18     Как обратится к обьекту класса, являющегося наследником абстрактного класса
Ответ Создать тему
Опции темы

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