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

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

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

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

31.07.2015, 23:58. Просмотров 2890. Ответов 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
Avazart
Эксперт С++
7262 / 5434 / 304
Регистрация: 10.12.2010
Сообщений: 24,158
Записей в блоге: 17
01.08.2015, 14:24 #61
Цитата Сообщение от DrOffset Посмотреть сообщение
Нарушает инкапсуляцию не friend, а программист, который неправильно его использует.
Ок, а как правильно?
friend в действительности мог бы предлагать больше, и точнее давать возможность задавать более жесткие правила доступа.

Выше я приводил пример с friend, мне нужен был доступ только к закрытым конструкторам классов, вместо этого я получал доступ ко всем закрытым членам.
0
Tulosba
:)
Эксперт С++
4397 / 3233 / 297
Регистрация: 19.02.2013
Сообщений: 9,045
01.08.2015, 14:36 #62
Цитата Сообщение от Avazart Посмотреть сообщение
мне нужен был доступ только к закрытым конструкторам классов, вместо этого я получал доступ ко всем закрытым членам.
Либо всё, либо ничего. Если хочется получить доступ только к какой-то конкретной части, то нужно эту часть выделить в самостоятельную сущность. Например сделать вложенный класс. Требовать чтобы friend класса имел доступ к ограниченном набору членов этого класса, довольно странно, т.к. это уже был бы и не друг класса вовсе.
0
Avazart
Эксперт С++
7262 / 5434 / 304
Регистрация: 10.12.2010
Сообщений: 24,158
Записей в блоге: 17
01.08.2015, 14:37 #63
Цитата Сообщение от Tulosba Посмотреть сообщение
Либо всё, либо ничего.
Ну это то как по факту есть, а не так как следовало бы.
Что это как не нарушение инкапсуляции когда предоставляется больше прав чем нужно/предполагается?

Цитата Сообщение от Tulosba Посмотреть сообщение
Если хочется получить доступ только к какой-то конкретной части, то нужно эту часть выделить в самостоятельную сущность.
Как мне "выделить" конструктор?
0
DrOffset
7377 / 4454 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
01.08.2015, 14:37 #64
Цитата Сообщение от Avazart Посмотреть сообщение
Ок, а как правильно?
Об этом много где есть.
Например для начала, можно было бы не давать доступ к данным класса всему ChainOfGasStation, а только методу, занимающемуся созданием экземпляра. Т.е. этот метод заменяет собой конструктор + устанавливает отношения взаимодействия и контракт, мы подчеркиваем, что только ChainOfGasStation::addCarGasStation может создать экземпляр. В этом случае не будет нарушения. Т.к. настоящий конструктор тоже имеет доступ ко всем данным - это равноценный обмен.
Уже был аналогичный вопрос, я постарался расписать все подробно (со ссылками на источники, чтобы не быть голословным): Использование инструмента friend в проекте
1
Avazart
Эксперт С++
7262 / 5434 / 304
Регистрация: 10.12.2010
Сообщений: 24,158
Записей в блоге: 17
01.08.2015, 14:42 #65
Цитата Сообщение от Tulosba Посмотреть сообщение
Требовать чтобы friend класса имел доступ к ограниченном набору членов этого класса, довольно странно, т.к. это уже был бы и не друг класса тогда.
Ну так дела не в соответствии названиию, а в затребованой возможности, как это назвать дело второстепенное.

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Например для начала, можно было бы не давать доступ к данным класса всему ChainOfGasStation, а только методу, занимающемуся созданием экземпляра.
Вполне логично, так и стоило сделать изначально, я просто не хотел заморачиваться с предъобявления только ради примера.
Но это никак не меняет сути проблемы из того метода нам по прежнему доступны все внутренности, когда нужен только конструктор.
0
hoggy
6728 / 2913 / 499
Регистрация: 15.11.2014
Сообщений: 6,550
Завершенные тесты: 1
01.08.2015, 14:56 #66
Цитата Сообщение от Avazart Посмотреть сообщение
Но это никак не меняет сути проблемы из того метода нам по прежнему доступны все внутренности, когда нужен только конструктор.
нету никакой проблемы.
и не нужно её создавать:

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

это - зряшная трата времени и сил.

задача - уберечься лишь от ничайных ошибок.
0
DrOffset
7377 / 4454 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
01.08.2015, 14:57 #67
Цитата Сообщение от Avazart Посмотреть сообщение
Вполне логично, так и стоило сделать изначально, я просто не хотел заморачиваться с предъобявления только ради примера.
Тем не менее это важное различие и снижает ценность примера, как доказательства "нарушения инкапсуляции".

Цитата Сообщение от Avazart Посмотреть сообщение
Но это никак не меняет сути проблемы из того метода нам по прежнему доступны все зарытые данные.
Цитата Сообщение от DrOffset Посмотреть сообщение
Т.к. настоящий конструктор тоже имеет доступ ко всем данным - это равноценный обмен.
В этом нет нарушения инкапсуляции. Пересмотри свой взгляд на эту проблему. Метод, который мы определили как friend (addCarGasStation), логически становится частью интерфейса CarGasStation. Нет ничего плохого в том, что ему доступны данные. Он логически - часть класса. Причем декларируем мы это не откуда угодно (тогда бы это было нарушением), а из самого класса CarGasStation, т.к. класс сам себя расширяет на еще один внешний метод. Когда ты добровольно отдаешь что-то - это не воровство, так ведь?
Поэтому Cтрауструп пишет о том, что человек, который пишет про однозначное нарушение инкапсуляции через friend - просто не до конца понимает терминологию С++.

Но если хочется еще больше, то можно разбить наш класс на собственно создающую часть и часть с данными\логикой. Сделать другом только создающую часть, т.к. friend не распространяется на наследование. Техническая возможность ограничить еще больше, существует.
0
Avazart
Эксперт С++
7262 / 5434 / 304
Регистрация: 10.12.2010
Сообщений: 24,158
Записей в блоге: 17
01.08.2015, 15:08 #68
В данном случае friend как продавец в супермаркете вы покупаете товар, а в место сдачи продавец вам дает жвачку и еще какую фигню которая вам не нада совсем.

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

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

Если немного пофантазировать то можно было бы придумать что-то вроде:

friend Chain for CarGusStation::CarGusStation();
Добавлено через 6 минут
Остался бы вопрос к целесообразности этого в плане реализации.
0
hoggy
6728 / 2913 / 499
Регистрация: 15.11.2014
Сообщений: 6,550
Завершенные тесты: 1
01.08.2015, 15:13 #69
Цитата Сообщение от Avazart Посмотреть сообщение
Дело не в защите, а логике вешей. Когда говоришь хочу именно это и получаешь что что просишь без всяких довесков.
дело в том, что проблема надуманная.
трех простых модификаторов доступа хватает за глаза.

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

Цитата Сообщение от Avazart Посмотреть сообщение
Ну так это и дает возможность к ошибится ибо не соблюдается логика.
ну вот нужно мне запретить создавать классы кому попало.
я выделил друга - функцию make.
функция make не занимается ничем, кроме создания.

ну и какие здесь проблемы с логикой?

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

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

Цитата Сообщение от Avazart Посмотреть сообщение
Если немного пофантазировать то можно было бы придумать что-то вроде:
friend Chain for CarGusStation::CarGusStation();
такой подход провоцирует чрезмерное раздутие правил без всякой необходимости.
синтаксис полюсов итак считается перегруженным.

нет причин, грузить его ещё больше вещами,
которые никаких реальных проблем не решают.
0
Avazart
Эксперт С++
7262 / 5434 / 304
Регистрация: 10.12.2010
Сообщений: 24,158
Записей в блоге: 17
01.08.2015, 15:17 #70
Цитата Сообщение от hoggy Посмотреть сообщение
такой подход провоцирует чрезмерное раздутие правил без всякой необходимости.
синтаксис полюсов итак считается перегруженным.
нет причин, грузить его ещё больше вещами,
которые никаких реальных проблем не решают.
Да ну ладно... я описал проблему и ее решение.
Как по мне значительная часть новшеств С++11 ничего не решает.

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
человек читает: "функция make создает объекты" - это все, что ему нужно знать для того,
Откуда он это читает, он видит фреанд в классе и тут чешит репу...
Потом лезит в этот класс-друг и там смотрит и чешит репу....
И так может метаться кобанчиком от одного к другому несколько раз.
0
DrOffset
7377 / 4454 / 1009
Регистрация: 30.01.2014
Сообщений: 7,304
01.08.2015, 15:18 #71
Цитата Сообщение от Avazart Посмотреть сообщение
Дело не в защите, а логике вешей. Когда говоришь хочу именно это и получаешь что что просишь без всяких довесков.
Именно так. Логика тут едина. Вот пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Base {};
 
class C : public Base
{
public:
    static std::unique_ptr<C> create()
    {
        std::unique_ptr<C> x(new C());
        x->v = 10;
        return x;
    }
    
private:
    C() {}
    
    int v;
};
Статический метод имеет доступ ко всем данным в классе. Пример компилируется.
Теперь делаем так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Base {};
 
class C : public Base
{
public:
    friend std::unique_ptr<C> create();
   
private:
    C() {}
    
    int v;
};
std::unique_ptr<C> create()
{
    std::unique_ptr<C> x(new C());
    x->v = 10;
    return x;
}
Что изменилось с точки зрения логики? Ничего. Вдумайся в это! Мы просто внесли внешнюю функцию в интерфейс класса. Она стала равноценна функции класса. Внес ее сам класс, он это решил. Здесь нет нарушения инкапсуляции, есть другой подход к организации интерфейса. У него естественно меньший приоритет, потому что он не такой естественный, но логически правила одинаковы.
0
Avazart
Эксперт С++
7262 / 5434 / 304
Регистрация: 10.12.2010
Сообщений: 24,158
Записей в блоге: 17
01.08.2015, 15:19 #72
Цитата Сообщение от hoggy Посмотреть сообщение
такой подход провоцирует чрезмерное раздутие правил без всякой необходимости.
И не раздутие, а строгость правил.
0
hoggy
6728 / 2913 / 499
Регистрация: 15.11.2014
Сообщений: 6,550
Завершенные тесты: 1
01.08.2015, 15:21 #73
Цитата Сообщение от Avazart Посмотреть сообщение
И не раздутие, а строгость правил.
ничем не обоснованное.

вы вообще осознаете,
что по сути то, что вы предлагаете,
это равносильно тому,
что бы отдельным частям класса ограничить доступ к другим частям этого же класса?
0
Avazart
Эксперт С++
7262 / 5434 / 304
Регистрация: 10.12.2010
Сообщений: 24,158
Записей в блоге: 17
01.08.2015, 15:26 #74
Цитата Сообщение от DrOffset Посмотреть сообщение
Вот пример:
Я чет не понял что пример демонстрирует то?

Добавлено через 47 секунд
Цитата Сообщение от hoggy Посмотреть сообщение
что бы отдельным частям класса ограничить доступ к другим частям этого же класса?
О_о вы наконец то поняли...
Да именно к этому я виду:
{
public only for Chine:
BusGusStation();
}
Но это конечно только фантазии на тему.
0
hoggy
6728 / 2913 / 499
Регистрация: 15.11.2014
Сообщений: 6,550
Завершенные тесты: 1
01.08.2015, 15:27 #75
Цитата Сообщение от Avazart Посмотреть сообщение
Откуда он это читает, он видит фреанд в классе и тут чешит репу...
C++
1
2
3
4
5
6
class sample
{
    sample();
 
    friend sample make();     // <--- о боже, и зачем это она френд.
};
Цитата Сообщение от Avazart Посмотреть сообщение
Потом лезит в этот класс-друг и там смотрит и чешит репу....
нафига?

Цитата Сообщение от Avazart Посмотреть сообщение
И так может метаться кобанчиком от одного к другому несколько раз.
нафига?

Добавлено через 1 минуту
Цитата Сообщение от Avazart Посмотреть сообщение
О_о вы наконец то поняли...
теперь осталось и вам понять:
Цитата Сообщение от Avazart Посмотреть сообщение
Я чет не понял что пример демонстрирует то?
потому что именно на этот нюанс пытается обратить ваше внимание господин DrOffset
0
01.08.2015, 15:27
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.08.2015, 15:27
Привет! Вот еще темы с ответами:

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

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

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

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


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

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

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