Форум программистов, компьютерный форум 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++ Как организовать интерфейс в виде абстрактного класса?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
 Аватар для Avazart
6905 / 5145 / 253
Регистрация: 10.12.2010
Сообщений: 22,630
Записей в блоге: 17
01.08.2015, 14:24     Как обратится к обьекту класса, являющегося наследником абстрактного класса #61
Цитата Сообщение от DrOffset Посмотреть сообщение
Нарушает инкапсуляцию не friend, а программист, который неправильно его использует.
Ок, а как правильно?
friend в действительности мог бы предлагать больше, и точнее давать возможность задавать более жесткие правила доступа.

Выше я приводил пример с friend, мне нужен был доступ только к закрытым конструкторам классов, вместо этого я получал доступ ко всем закрытым членам.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
01.08.2015, 14:36     Как обратится к обьекту класса, являющегося наследником абстрактного класса #62
Цитата Сообщение от Avazart Посмотреть сообщение
мне нужен был доступ только к закрытым конструкторам классов, вместо этого я получал доступ ко всем закрытым членам.
Либо всё, либо ничего. Если хочется получить доступ только к какой-то конкретной части, то нужно эту часть выделить в самостоятельную сущность. Например сделать вложенный класс. Требовать чтобы friend класса имел доступ к ограниченном набору членов этого класса, довольно странно, т.к. это уже был бы и не друг класса вовсе.
Avazart
 Аватар для Avazart
6905 / 5145 / 253
Регистрация: 10.12.2010
Сообщений: 22,630
Записей в блоге: 17
01.08.2015, 14:37     Как обратится к обьекту класса, являющегося наследником абстрактного класса #63
Цитата Сообщение от Tulosba Посмотреть сообщение
Либо всё, либо ничего.
Ну это то как по факту есть, а не так как следовало бы.
Что это как не нарушение инкапсуляции когда предоставляется больше прав чем нужно/предполагается?

Цитата Сообщение от Tulosba Посмотреть сообщение
Если хочется получить доступ только к какой-то конкретной части, то нужно эту часть выделить в самостоятельную сущность.
Как мне "выделить" конструктор?
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
01.08.2015, 14:37     Как обратится к обьекту класса, являющегося наследником абстрактного класса #64
Цитата Сообщение от Avazart Посмотреть сообщение
Ок, а как правильно?
Об этом много где есть.
Например для начала, можно было бы не давать доступ к данным класса всему ChainOfGasStation, а только методу, занимающемуся созданием экземпляра. Т.е. этот метод заменяет собой конструктор + устанавливает отношения взаимодействия и контракт, мы подчеркиваем, что только ChainOfGasStation::addCarGasStation может создать экземпляр. В этом случае не будет нарушения. Т.к. настоящий конструктор тоже имеет доступ ко всем данным - это равноценный обмен.
Уже был аналогичный вопрос, я постарался расписать все подробно (со ссылками на источники, чтобы не быть голословным): Использование инструмента friend в проекте
Avazart
 Аватар для Avazart
6905 / 5145 / 253
Регистрация: 10.12.2010
Сообщений: 22,630
Записей в блоге: 17
01.08.2015, 14:42     Как обратится к обьекту класса, являющегося наследником абстрактного класса #65
Цитата Сообщение от Tulosba Посмотреть сообщение
Требовать чтобы friend класса имел доступ к ограниченном набору членов этого класса, довольно странно, т.к. это уже был бы и не друг класса тогда.
Ну так дела не в соответствии названиию, а в затребованой возможности, как это назвать дело второстепенное.

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

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

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

задача - уберечься лишь от ничайных ошибок.
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
01.08.2015, 14:57     Как обратится к обьекту класса, являющегося наследником абстрактного класса #67
Цитата Сообщение от Avazart Посмотреть сообщение
Вполне логично, так и стоило сделать изначально, я просто не хотел заморачиваться с предъобявления только ради примера.
Тем не менее это важное различие и снижает ценность примера, как доказательства "нарушения инкапсуляции".

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

Но если хочется еще больше, то можно разбить наш класс на собственно создающую часть и часть с данными\логикой. Сделать другом только создающую часть, т.к. friend не распространяется на наследование. Техническая возможность ограничить еще больше, существует.
Avazart
 Аватар для Avazart
6905 / 5145 / 253
Регистрация: 10.12.2010
Сообщений: 22,630
Записей в блоге: 17
01.08.2015, 15:08     Как обратится к обьекту класса, являющегося наследником абстрактного класса #68
В данном случае friend как продавец в супермаркете вы покупаете товар, а в место сдачи продавец вам дает жвачку и еще какую фигню которая вам не нада совсем.

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

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

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

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

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

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

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

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

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

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

нет причин, грузить его ещё больше вещами,
которые никаких реальных проблем не решают.
Avazart
 Аватар для Avazart
6905 / 5145 / 253
Регистрация: 10.12.2010
Сообщений: 22,630
Записей в блоге: 17
01.08.2015, 15:17     Как обратится к обьекту класса, являющегося наследником абстрактного класса #70
Цитата Сообщение от hoggy Посмотреть сообщение
такой подход провоцирует чрезмерное раздутие правил без всякой необходимости.
синтаксис полюсов итак считается перегруженным.
нет причин, грузить его ещё больше вещами,
которые никаких реальных проблем не решают.
Да ну ладно... я описал проблему и ее решение.
Как по мне значительная часть новшеств С++11 ничего не решает.

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
человек читает: "функция make создает объекты" - это все, что ему нужно знать для того,
Откуда он это читает, он видит фреанд в классе и тут чешит репу...
Потом лезит в этот класс-друг и там смотрит и чешит репу....
И так может метаться кобанчиком от одного к другому несколько раз.
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
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;
}
Что изменилось с точки зрения логики? Ничего. Вдумайся в это! Мы просто внесли внешнюю функцию в интерфейс класса. Она стала равноценна функции класса. Внес ее сам класс, он это решил. Здесь нет нарушения инкапсуляции, есть другой подход к организации интерфейса. У него естественно меньший приоритет, потому что он не такой естественный, но логически правила одинаковы.
Avazart
 Аватар для Avazart
6905 / 5145 / 253
Регистрация: 10.12.2010
Сообщений: 22,630
Записей в блоге: 17
01.08.2015, 15:19     Как обратится к обьекту класса, являющегося наследником абстрактного класса #72
Цитата Сообщение от hoggy Посмотреть сообщение
такой подход провоцирует чрезмерное раздутие правил без всякой необходимости.
И не раздутие, а строгость правил.
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
01.08.2015, 15:21     Как обратится к обьекту класса, являющегося наследником абстрактного класса #73
Цитата Сообщение от Avazart Посмотреть сообщение
И не раздутие, а строгость правил.
ничем не обоснованное.

вы вообще осознаете,
что по сути то, что вы предлагаете,
это равносильно тому,
что бы отдельным частям класса ограничить доступ к другим частям этого же класса?
Avazart
 Аватар для Avazart
6905 / 5145 / 253
Регистрация: 10.12.2010
Сообщений: 22,630
Записей в блоге: 17
01.08.2015, 15:26     Как обратится к обьекту класса, являющегося наследником абстрактного класса #74
Цитата Сообщение от DrOffset Посмотреть сообщение
Вот пример:
Я чет не понял что пример демонстрирует то?

Добавлено через 47 секунд
Цитата Сообщение от hoggy Посмотреть сообщение
что бы отдельным частям класса ограничить доступ к другим частям этого же класса?
О_о вы наконец то поняли...
Да именно к этому я виду:
{
public only for Chine:
BusGusStation();
}
Но это конечно только фантазии на тему.
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 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
DrOffset
6461 / 3835 / 886
Регистрация: 30.01.2014
Сообщений: 6,630
01.08.2015, 15:33     Как обратится к обьекту класса, являющегося наследником абстрактного класса #76
Цитата Сообщение от Avazart Посмотреть сообщение
Я чет не понял что пример демонстрирует то?
Там все написано.
Демонстрирует то, зачем вообще нужен friend. Это альтернативный способ организации интерфейса. Когда мы пишем метод в классе, то почему у нас не возникает желания оставить ему в пользование только часть данных? Сказать: метод x класса А имеет право доступа только к данным а и b класса А, но к данным c и d - не имеет.
Пример демонстрирует, что для friend правила такие же как для членов класса. Точно так же как не существует подобного ограничения для членов класса, не существует его и для friend.
Avazart
 Аватар для Avazart
6905 / 5145 / 253
Регистрация: 10.12.2010
Сообщений: 22,630
Записей в блоге: 17
01.08.2015, 15:33     Как обратится к обьекту класса, являющегося наследником абстрактного класса #77
C++
1
2
3
4
5
 class sample 
{ 
       sample(); 
       friend some::hardcore(); 
}
А если так?
Я не узнаю пока не полезу в hardcore() где увижу что в hardcore() где возможно вызываются закрытые методы и мне опять нужно будет вернуться к классу sample
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
01.08.2015, 15:35     Как обратится к обьекту класса, являющегося наследником абстрактного класса #78
Цитата Сообщение от Avazart Посмотреть сообщение
А если так?
а если так?

C++
1
2
3
4
5
6
7
8
9
class ffsdf
{ 
       ffsdf(); 
       friend ffsdf tyltry(); 
 
int    dfkdflgk;
 
     float dgklhg(int gfg);
};
мож не нужно доводить до маразма?
Avazart
 Аватар для Avazart
6905 / 5145 / 253
Регистрация: 10.12.2010
Сообщений: 22,630
Записей в блоге: 17
01.08.2015, 15:44     Как обратится к обьекту класса, являющегося наследником абстрактного класса #79
Цитата Сообщение от hoggy Посмотреть сообщение
мож не нужно доводить до маразма?
А при чем тут маразм? Дело то не ограничиватеся только созданием(make) могу выполнятся и другие действия.
hardcore() вполне может быть вменяемым названием, но ее имя не скажет точно с чем из защиенных внутренностей данного класса она работает, для этого мне придется листать код к её определению. Т.е менее информативно.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.08.2015, 15:56     Как обратится к обьекту класса, являющегося наследником абстрактного класса
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
01.08.2015, 15:56     Как обратится к обьекту класса, являющегося наследником абстрактного класса #80
Цитата Сообщение от Avazart Посмотреть сообщение
А при чем тут маразм? Дело то не ограничиватеся созданием(make) могу выполнятся и другие действия.
1.
пользователя не касается, что там под капотом чужого класса.

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

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

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

имя не должно никак светить подробности реализации.
Yandex
Объявления
01.08.2015, 15:56     Как обратится к обьекту класса, являющегося наследником абстрактного класса
Ответ Создать тему
Опции темы

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