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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 4.72
irises
69 / 26 / 8
Регистрация: 29.06.2015
Сообщений: 105
#1

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

31.07.2015, 23:58. Просмотров 2832. Ответов 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
Eraston
53 / 10 / 2
Регистрация: 09.09.2014
Сообщений: 127
01.08.2015, 00:46 #16
Цитата Сообщение от Avazart Посмотреть сообщение
Членный класса всегда должны быть закрытыми, а не защищенными.
Да что вы? А как вы их наследовать будете? Если мне память не изменяет, private-члены ни при каких условиях потомкам не переходят.
0
Avazart
Нарушитель
Эксперт С++
7233 / 5405 / 294
Регистрация: 10.12.2010
Сообщений: 23,956
Записей в блоге: 17
01.08.2015, 00:56 #17
Касательно инициализации через конструктор базового класса.
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
class AbstractGasStation
{ 
  public:
  /*Никаких друзей*/
   virtual ~AbstractGasStation(){}; /*Виртуальный деструктор!*/
   void AbstractGasStation(){};
   AbstractGasStation(double A92,double A95,double A98) // Конструктор с параметрами инициализирущими начальные значения.
    :A92_(A92), // Список инициализации
     A95_(A95)
     A98_(A98)
    {};
  // твой код
};
 
class CarGasStation : public AbstractGasStation
{
  public:
   CarGasStation():AbstractGasStation(10,20,30){};// Инициализируем используя конструктор базового класса.
  // твой код
};
 
class TruckGasStation : public AbstractGasStation
{
  public:
    TruckGasStation():AbstractGasStation(40,50,60){};
  // твой код
};
Но опять нужно смотреть задание, понимать что общее между этими двумя классами и чем они отличаются.
Что выносить в базовый класс(общее) а что нет, и вообще смысл всего этого.
0
Eraston
53 / 10 / 2
Регистрация: 09.09.2014
Сообщений: 127
01.08.2015, 00:56 #18
Это, конечно, вопрос подхода.
Мне вот "очень удобно" внутри своих классов таким бредом маяться:
SetVar( GetVar + 8 );
вместо
Var += 8;
0
Avazart
Нарушитель
Эксперт С++
7233 / 5405 / 294
Регистрация: 10.12.2010
Сообщений: 23,956
Записей в блоге: 17
01.08.2015, 01:00 #19
Цитата Сообщение от Eraston Посмотреть сообщение
Да что вы? А как вы их наследовать будете? Если мне память не изменяет, private-члены ни при каких условиях потомкам не переходят.
Они то "переходят" но они становятся "недоступными" для этого я и определили открытые методы-акцессоры.

Добавлено через 1 минуту
Цитата Сообщение от Eraston Посмотреть сообщение
Это, конечно, вопрос подхода.
Нет, это вопрос инкапсуляции.
К тому же акцессоры можно делать "ссылочными".
C++
1
obj.var()+= 8;
0
Eraston
53 / 10 / 2
Регистрация: 09.09.2014
Сообщений: 127
01.08.2015, 01:04 #20
Цитата Сообщение от Avazart Посмотреть сообщение
Они то "переходят" но они становятся "недоступными" для этого я и определили открытые методы-акцессоры.
В классе 20 переменных, для каждой писать гетсеты? Хуже того - впоследствии, пользоваться ими? Учитывая, что protected-члены также недоступны вне классов, а в пределах класса они всё равно являются что private, что protected, с разницей в уровне удобства доступа...
0
Avazart
Нарушитель
Эксперт С++
7233 / 5405 / 294
Регистрация: 10.12.2010
Сообщений: 23,956
Записей в блоге: 17
01.08.2015, 01:06 #21
Цитата Сообщение от Eraston Посмотреть сообщение
В классе 20 переменных, для каждой писать гетсеты?
Обязательно.

Добавлено через 1 минуту
Eraston, Почитайте книгу Саттера и прекращайте быдлокодить....
0
Eraston
53 / 10 / 2
Регистрация: 09.09.2014
Сообщений: 127
01.08.2015, 01:10 #22
Avazart, грань между инкапсуляцией и сокрытием довольно тонкая.
0
irises
69 / 26 / 8
Регистрация: 29.06.2015
Сообщений: 105
01.08.2015, 01:15  [ТС] #23
Цитата Сообщение от Avazart Посмотреть сообщение
Как то так:
это просто прям отличный образец кода, то что надо! точно же, можно было использовать шаблонный класс, чтоб упростить дело с массивами
Цитата Сообщение от Avazart Посмотреть сообщение
Что выносить в базовый класс(общее) а что нет, и вообще смысл всего этого.
вот поэтому общее (это марки бензина и цистерны) я вынесла в абстрактный класс, а их различия (цена бензина и макс объем цистерн) уже инициализировала отдельно в классах

private-члены ни при каких условиях потомкам не переходят.
и вот поэтому сделала поля защищенными, чтоб использовать общие поля (я никак не могла припомнить почему нам говорили делать эти поля защищенными, но теперь я этого уж точно не забуду)
0
Eraston
53 / 10 / 2
Регистрация: 09.09.2014
Сообщений: 127
01.08.2015, 01:15 #24
Avazart, я согласен, что необходимо полностью закрывать доступ к членам сложных типов данных типа (TreeNode, File, List, Table, Array и пр. являющихся составными, и, тем более, работающих с указателями), но абсолютно не вижу смысла закрывать простые int'ы c float'ами. Возможно, с практикой и опытом моё мнение и изменится.
0
Avazart
Нарушитель
Эксперт С++
7233 / 5405 / 294
Регистрация: 10.12.2010
Сообщений: 23,956
Записей в блоге: 17
01.08.2015, 01:21 #25
Инкапсуляция подразумевает скрытие, или точнее сказать ограничение доступа, "скрытие внутренностей".

Добавлено через 3 минуты
Цитата Сообщение от irises Посмотреть сообщение
вот поэтому общее (это марки бензина и цистерны) я вынесла в абстрактный класс, а их различия (цена бензина и макс объем цистерн) уже инициализировала отдельно в классах
Ну это не такое уже и различие если учесть что эти поля можно задавать при создании и менять в процессе через конструктор или сетторы.
Разница была бы если бы к примеру на "грузовой заправке" продавалась бы еще дизель топливо к примеру.
Если уже должно быть "жестко" заданые значения то вероятно стоит использовать сonst- переменные, для итовых еще можно "переопределять" enum
Да и вероятно конструктор с параметрами базового класса вероятно стоит сделать protected.

Добавлено через 55 секунд
Цитата Сообщение от irises Посмотреть сообщение
и вот поэтому сделала поля защищенными, чтоб использовать общие поля (я никак не могла припомнить почему нам говорили делать эти поля защищенными, но теперь я этого уж точно не забуду)
Не нужно их делать защищенными, защищенными обычно делаю методы, а не члены класса.
Члены класса- закрытыми.
0
irises
69 / 26 / 8
Регистрация: 29.06.2015
Сообщений: 105
01.08.2015, 01:28  [ТС] #26
Цитата Сообщение от Avazart Посмотреть сообщение
Ну это не такое уже и различие если учесть что эти поля можно задавать при создании и менять в процессе.
Разница была бы если бы к примеру на "грузовой заправке" продавалась бы еще дизель топливо к примеру.
ну почему же задавать, они прописаны в конструкторе по умолчанию и в процессе уже никак не меняются

Цитата Сообщение от Avazart Посмотреть сообщение
Не нужно их делать защищенными, защищенными обычно делаю методы, а не члены класса.
Члены класса- закрытыми.
хорошо, убедили, я исправлю свой код и буду учится сразу писать правильно, ведь даже если будет хоть 20 переменных, то нужно делать 40 методов (set и get)
0
Avazart
Нарушитель
Эксперт С++
7233 / 5405 / 294
Регистрация: 10.12.2010
Сообщений: 23,956
Записей в блоге: 17
01.08.2015, 01:33 #27
Ну так методов вобще может не быть.
К примеру геттер в вашем случае может присутствовать, а сеттеры могут и отсутствовать- т.е не будет возможности изменить значение. Для этого собственно и разделяется доступ на геттеры и сеттры.
Более того сеттеры и геттеры могу делать что-то еще помимо установки значения так называемое "последействие" и повидение может менятся от базового члена класса к наследникам, чего не достикнуть если открывать/"защищать" членны-данные.
0
irises
69 / 26 / 8
Регистрация: 29.06.2015
Сообщений: 105
01.08.2015, 01:38  [ТС] #28
Цитата Сообщение от Avazart Посмотреть сообщение
Ну так методов вобще может не быть.
это я образно, все зависит от способа написания программы, иногда нужно только сеттеры или только геттеры, или то и другое одновременно
0
rikimaru2013
C++ Game Dev
2438 / 1132 / 240
Регистрация: 30.11.2013
Сообщений: 3,688
01.08.2015, 01:42 #29
Цитата Сообщение от Eraston Посмотреть сообщение
но абсолютно не вижу смысла закрывать простые int'ы c float'ами. Возможно, с практикой и опытом моё мнение и изменится.
Напишите класс Дробь у которого открты поля знаменатель и числитель, и дайте друзьям "поиграться" и засекайте за сколько минут у них кританёт и они напишут, что ваш код гавно после кода
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Drob
    {
    public:
        int x;
        int y;
 
        float       toFloat() const
        {
            return x*1.0 / y;
        }
    };
 
 
Drob a(10, 0);
cout << a.toFloat() << endl;
0
Avazart
Нарушитель
Эксперт С++
7233 / 5405 / 294
Регистрация: 10.12.2010
Сообщений: 23,956
Записей в блоге: 17
01.08.2015, 02:02 #30
Цитата Сообщение от irises Посмотреть сообщение
это я образно, все зависит от способа написания программы, иногда нужно только сеттеры или только геттеры, или то и другое одновременно
А может примеру и так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public:
    enum Mark{ A92,A95,A98 }; 
// A92= 0 ,A95= 1, A98= 2 - будут использоваться как индексы массива.
 
    const double& benzine(Mark mark)const{  return  A_[mark]; } // геттер
    double& benzine(Mark mark){  return  A_[mark]; } // по сути сеттер
 
private:
    double A_[3];// A92,A95,A98
}
 
//
 
double a95= station.benzine(AbstractGusStation::A95);
station.benzine(A95)+= 5; // Увеличиваем на 5 значение засчет возврата ссылки
0
01.08.2015, 02:02
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.08.2015, 02:02
Привет! Вот еще темы с ответами:

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

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

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

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


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

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

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