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

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

31.07.2015, 23:58. Показов 10198. Ответов 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
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 14:24
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от DrOffset Посмотреть сообщение
Нарушает инкапсуляцию не friend, а программист, который неправильно его использует.
Ок, а как правильно?
friend в действительности мог бы предлагать больше, и точнее давать возможность задавать более жесткие правила доступа.

Выше я приводил пример с friend, мне нужен был доступ только к закрытым конструкторам классов, вместо этого я получал доступ ко всем закрытым членам.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
01.08.2015, 14:36
Цитата Сообщение от Avazart Посмотреть сообщение
мне нужен был доступ только к закрытым конструкторам классов, вместо этого я получал доступ ко всем закрытым членам.
Либо всё, либо ничего. Если хочется получить доступ только к какой-то конкретной части, то нужно эту часть выделить в самостоятельную сущность. Например сделать вложенный класс. Требовать чтобы friend класса имел доступ к ограниченном набору членов этого класса, довольно странно, т.к. это уже был бы и не друг класса вовсе.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 14:37
Цитата Сообщение от Tulosba Посмотреть сообщение
Либо всё, либо ничего.
Ну это то как по факту есть, а не так как следовало бы.
Что это как не нарушение инкапсуляции когда предоставляется больше прав чем нужно/предполагается?

Цитата Сообщение от Tulosba Посмотреть сообщение
Если хочется получить доступ только к какой-то конкретной части, то нужно эту часть выделить в самостоятельную сущность.
Как мне "выделить" конструктор?
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
01.08.2015, 14:37
Цитата Сообщение от Avazart Посмотреть сообщение
Ок, а как правильно?
Об этом много где есть.
Например для начала, можно было бы не давать доступ к данным класса всему ChainOfGasStation, а только методу, занимающемуся созданием экземпляра. Т.е. этот метод заменяет собой конструктор + устанавливает отношения взаимодействия и контракт, мы подчеркиваем, что только ChainOfGasStation::addCarGasStation может создать экземпляр. В этом случае не будет нарушения. Т.к. настоящий конструктор тоже имеет доступ ко всем данным - это равноценный обмен.
Уже был аналогичный вопрос, я постарался расписать все подробно (со ссылками на источники, чтобы не быть голословным): https://www.cyberforum.ru/post7804066.html
1
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 14:42
Цитата Сообщение от Tulosba Посмотреть сообщение
Требовать чтобы friend класса имел доступ к ограниченном набору членов этого класса, довольно странно, т.к. это уже был бы и не друг класса тогда.
Ну так дела не в соответствии названиию, а в затребованой возможности, как это назвать дело второстепенное.

Добавлено через 2 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Например для начала, можно было бы не давать доступ к данным класса всему ChainOfGasStation, а только методу, занимающемуся созданием экземпляра.
Вполне логично, так и стоило сделать изначально, я просто не хотел заморачиваться с предъобявления только ради примера.
Но это никак не меняет сути проблемы из того метода нам по прежнему доступны все внутренности, когда нужен только конструктор.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.08.2015, 14:56
Цитата Сообщение от Avazart Посмотреть сообщение
Но это никак не меняет сути проблемы из того метода нам по прежнему доступны все внутренности, когда нужен только конструктор.
нету никакой проблемы.
и не нужно её создавать:

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

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

задача - уберечься лишь от ничайных ошибок.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
01.08.2015, 14:57
Цитата Сообщение от Avazart Посмотреть сообщение
Вполне логично, так и стоило сделать изначально, я просто не хотел заморачиваться с предъобявления только ради примера.
Тем не менее это важное различие и снижает ценность примера, как доказательства "нарушения инкапсуляции".

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

Но если хочется еще больше, то можно разбить наш класс на собственно создающую часть и часть с данными\логикой. Сделать другом только создающую часть, т.к. friend не распространяется на наследование. Техническая возможность ограничить еще больше, существует.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 15:08
В данном случае friend как продавец в супермаркете вы покупаете товар, а в место сдачи продавец вам дает жвачку и еще какую фигню которая вам не нада совсем.

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

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

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

friend Chain for CarGusStation::CarGusStation();
Добавлено через 6 минут
Остался бы вопрос к целесообразности этого в плане реализации.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.08.2015, 15:13
Цитата Сообщение от Avazart Посмотреть сообщение
Дело не в защите, а логике вешей. Когда говоришь хочу именно это и получаешь что что просишь без всяких довесков.
дело в том, что проблема надуманная.
трех простых модификаторов доступа хватает за глаза.

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

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

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

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

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

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

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

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
человек читает: "функция make создает объекты" - это все, что ему нужно знать для того,
Откуда он это читает, он видит фреанд в классе и тут чешит репу...
Потом лезит в этот класс-друг и там смотрит и чешит репу....
И так может метаться кобанчиком от одного к другому несколько раз.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
01.08.2015, 15:18
Цитата Сообщение от 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
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 15:19
Цитата Сообщение от hoggy Посмотреть сообщение
такой подход провоцирует чрезмерное раздутие правил без всякой необходимости.
И не раздутие, а строгость правил.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.08.2015, 15:21
Цитата Сообщение от Avazart Посмотреть сообщение
И не раздутие, а строгость правил.
ничем не обоснованное.

вы вообще осознаете,
что по сути то, что вы предлагаете,
это равносильно тому,
что бы отдельным частям класса ограничить доступ к другим частям этого же класса?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 15:26
Цитата Сообщение от DrOffset Посмотреть сообщение
Вот пример:
Я чет не понял что пример демонстрирует то?

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

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

Добавлено через 1 минуту
Цитата Сообщение от Avazart Посмотреть сообщение
О_о вы наконец то поняли...
теперь осталось и вам понять:
Цитата Сообщение от Avazart Посмотреть сообщение
Я чет не понял что пример демонстрирует то?
потому что именно на этот нюанс пытается обратить ваше внимание господин DrOffset
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
01.08.2015, 15:33
Цитата Сообщение от Avazart Посмотреть сообщение
Я чет не понял что пример демонстрирует то?
Там все написано.
Демонстрирует то, зачем вообще нужен friend. Это альтернативный способ организации интерфейса. Когда мы пишем метод в классе, то почему у нас не возникает желания оставить ему в пользование только часть данных? Сказать: метод x класса А имеет право доступа только к данным а и b класса А, но к данным c и d - не имеет.
Пример демонстрирует, что для friend правила такие же как для членов класса. Точно так же как не существует подобного ограничения для членов класса, не существует его и для friend.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 15:33
C++
1
2
3
4
5
 class sample 
{ 
       sample(); 
       friend some::hardcore(); 
}
А если так?
Я не узнаю пока не полезу в hardcore() где увижу что в hardcore() где возможно вызываются закрытые методы и мне опять нужно будет вернуться к классу sample
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.08.2015, 15:35
Цитата Сообщение от Avazart Посмотреть сообщение
А если так?
а если так?

C++
1
2
3
4
5
6
7
8
9
class ffsdf
{ 
       ffsdf(); 
       friend ffsdf tyltry(); 
 
int    dfkdflgk;
 
     float dgklhg(int gfg);
};
мож не нужно доводить до маразма?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
01.08.2015, 15:44
Цитата Сообщение от hoggy Посмотреть сообщение
мож не нужно доводить до маразма?
А при чем тут маразм? Дело то не ограничиватеся только созданием(make) могу выполнятся и другие действия.
hardcore() вполне может быть вменяемым названием, но ее имя не скажет точно с чем из защиенных внутренностей данного класса она работает, для этого мне придется листать код к её определению. Т.е менее информативно.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
01.08.2015, 15:56
Цитата Сообщение от Avazart Посмотреть сообщение
А при чем тут маразм? Дело то не ограничиватеся созданием(make) могу выполнятся и другие действия.
1.
пользователя не касается, что там под капотом чужого класса.

2.
разработчик знает, что под капотом его собственного класса.

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

Добавлено через 3 минуты
Цитата Сообщение от Avazart Посмотреть сообщение
hardcore() вполне может быть вменяемым названием, но ее имя не скажет точно с чем из защиенных внутренностей данного класса она работает,
имя функции-члена должно отражать умение механизма.
hardcore в сферическом ваккуме мне ни о чем не говорит, например.

имя не должно никак светить подробности реализации.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.08.2015, 15:56

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

Метод абстрактного класса не видит переменные дочернего класса
есть 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;); ...


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
интеграция 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 на бесплатном хостинге: Двухдневный лог борьбы Всем привет! Хочу поделиться свежим (и довольно. . .
Где деньги лежат
kumehtar 02.07.2026
Это - японская подводная лодка I-52 (тип C2, кодовое имя Momi) вышла из Японии в марте 1944 года с миссией в оккупированную немцами Францию (Лорьян). Это была одна из «Янаги»-миссий по обмену. . .
Krabik для WoW 3.3.5a, многоязычный
AmbA 02.07.2026
Допилил бота, думаю что окончательно. Изменения: - добавлена многоязычность - добавлено снятие скриншотов - добавлено поддержание бафов хождения по воде (для жреца, дк и шамана) - и так, по. . .
Алиса нашла кучу ошибок компиляции и запуска в проекте, который без проблем компилировался и запускался)))
anaschu 30.06.2026
Я пока посмеюся, но завтра проверю. А вообще интерсно. Дал алисе файл, в котором точно нет ошибок компиляции и запуска, и попросил их найти. Нашла кучу))) Критические ошибки, мешающие компиляции и. . .
сукцессия 16. Общий обзор, в основном что бы другие ии поняли
anaschu 29.06.2026
# Передаточный документ: модель микоризной сукцессии (для нового чата) Этот документ предназначен для того, чтобы новый чат Claude мог продолжить работу без необходимости заново разбираться в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru