Форум программистов, компьютерный форум 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
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,629
Записей в блоге: 17
01.08.2015, 16:01     Как обратится к обьекту класса, являющегося наследником абстрактного класса #81
Цитата Сообщение от DrOffset Посмотреть сообщение
Здесь нет нарушения инкапсуляции, есть другой подход к организации интерфейса.
Естественно нет, ибо один класс не лезит в другой...
Да и по сути, что это код делает?
К примеру чем тут конструктор не устроил?

Добавлено через 3 минуты
Цитата Сообщение от hoggy Посмотреть сообщение
1.
пользователя не касается, что там под капотом чужого класса.
Цитата Сообщение от hoggy Посмотреть сообщение
2.
разработчик знает, что под капотом его собственного класса.
Ну.. ну... пользователь это разработчик спустя несколько месяцев .... когда все уже подзабылось.

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
имя не должно никак светить подробности реализации.
Имя нет, о чем я и пытался сказать, а вот "фриенд-объявление" неплохо бы что бы говорило, точнее сказать что давало больше информации об "отношениях" к этому классу.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
01.08.2015, 16:06     Как обратится к обьекту класса, являющегося наследником абстрактного класса #82
Цитата Сообщение от Avazart Посмотреть сообщение
Ну.. ну... пользователь это разработчик спустя несколько месяцев .... когда все уже подзабылось.
ну и что?

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

"пьяный проспится, дурак - никогда"(ц)Петр 1.


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

Добавлено через 56 секунд
Цитата Сообщение от Avazart Посмотреть сообщение
Имя нет, о чем я и пытался сказать, а вот "фриенд-объявление" неплохо бы что бы говорило, точнее сказать что давало больше информации об "отношениях" к этому классу.
если вы считаете, что имя не достаточно понятное - ну дайте более понятное.
DrOffset
6459 / 3833 / 885
Регистрация: 30.01.2014
Сообщений: 6,628
01.08.2015, 16:22     Как обратится к обьекту класса, являющегося наследником абстрактного класса #83
Цитата Сообщение от Avazart Посмотреть сообщение
Да и по сути, что это код делает?
К примеру чем тут конструктор не устроил?
Это демонстрационный пример. Детали не играют роли, главное там - это строки 9 и 16, которые демонстрируют ноль отличий, с точки зрения доступа к данным класса.

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

PS. Вообще, если интересно, демонстрационный пример использовал в основе эту идиому: https://en.wikibooks.org/wiki/More_C...ed_Constructor
Однако это напрямую не относится к обсуждаемому вопросу.
smartpointer
 Аватар для smartpointer
64 / 58 / 23
Регистрация: 17.02.2014
Сообщений: 250
01.08.2015, 16:48     Как обратится к обьекту класса, являющегося наследником абстрактного класса #84
Цитата Сообщение от DrOffset Посмотреть сообщение
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;
}
Это называется как загнать себя в угол с инкапсуляцией.По идеи пример не имеет право на жизнь. Потому как я не смогу сделать вот так.
C++
1
2
3
4
5
6
7
8
class D : public C
{
};
int main()
{
    D d;
    return 0;
}
Класс C сам должен быть инкапсулирован . Чтобы юзер не смог вообще его видеть.Или нам нужно решение в виде костылей ?
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
01.08.2015, 17:02     Как обратится к обьекту класса, являющегося наследником абстрактного класса #85
Цитата Сообщение от smartpointer Посмотреть сообщение
Это называется как загнать себя в угол с инкапсуляцией.По идеи пример не имеет право на жизнь. Потому как я не смогу сделать вот так.
Цитата Сообщение от smartpointer Посмотреть сообщение
Класс C сам должен быть инкапсулирован . Чтобы юзер не смог вообще его видеть.Или нам нужно решение в виде костылей ?
сложно предполагать, что вы понимаете под инкапсуляцией.
но в голове у вас конкретная каша.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,629
Записей в блоге: 17
01.08.2015, 17:07     Как обратится к обьекту класса, являющегося наследником абстрактного класса #86
Цитата Сообщение от DrOffset Посмотреть сообщение
Это демонстрационный пример. Детали не играют роли, главное там - это строки 9 и 16, которые демонстрируют ноль отличий, с точки зрения доступа к данным класса.
Да как раз дьявал в деталях.

Цитата Сообщение от DrOffset Посмотреть сообщение
В С++ есть много идиом, которые без упоминания конкретной задачи могут показаться бредом.
А я о чем... твой код бред .. непонятно что делает, для чего и как.
Класс Base пустой.... явно чего то нехватает...

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

Добавлено через 48 секунд
Цитата Сообщение от hoggy Посмотреть сообщение
я смотрю на то, что код делает по факту.
а не на то, чего он мог бы сделать,
или не мог.
Ну вот и я про то нужно смотреть, не интуитивно...

Добавлено через 45 секунд
Цитата Сообщение от hoggy Посмотреть сообщение
если вы считаете, что имя не достаточно понятное - ну дайте более понятное.
Так а я о чем нет таких средств в С++.
smartpointer
 Аватар для smartpointer
64 / 58 / 23
Регистрация: 17.02.2014
Сообщений: 250
01.08.2015, 17:17     Как обратится к обьекту класса, являющегося наследником абстрактного класса #87
Цитата Сообщение от hoggy Посмотреть сообщение
сложно предполагать, что вы понимаете под инкапсуляцией.
Так же как и вы. Тык или не ?
Цитата Сообщение от hoggy Посмотреть сообщение
но в голове у вас конкретная каша.
Ну так приведите контр-пример или типа классы не могут быть скрытыми ?
P.S меньше читайте всяких умников - больше пишите кода, иначе только забьете голову всяким бредом так и не научившись кодить
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
01.08.2015, 17:31     Как обратится к обьекту класса, являющегося наследником абстрактного класса #88
Цитата Сообщение от Avazart Посмотреть сообщение
Добро пожаловать в Си и Asm там все просто...
мне и на плюсах не плохо.

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

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

ничто не мешает писать понятный код.

откуда у вас такая нужда возникла,
это вопрос отдельный, и открытый.

явно не из-за декларации в приватной части класса некого френда.

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

Цитата Сообщение от smartpointer Посмотреть сообщение
Так же как и вы. Тык или не ?
похоже, что не.

Цитата Сообщение от smartpointer Посмотреть сообщение
Ну так приведите контр-пример или типа классы не могут быть скрытыми ?
1.
Инкапсуляция данных - это не сокрытие данных.

2.
в примере выше у класса был закрыт конструктор.
автор этого кода сделал это специально.

ваша реакция на это показывает,
что вы не осознаете сути момента.

в частности:
Цитата Сообщение от smartpointer Посмотреть сообщение
Потому как я не смогу сделать вот так.
вот именно для этого конструктор и был сознательно закрыт его создателем.

что бы такие как вы,
которые не в теме,
не смогли отстрелить себе ноги.

Добавлено через 1 минуту
Цитата Сообщение от smartpointer Посмотреть сообщение
P.S меньше читайте всяких умников - больше пишите кода, иначе только забьете голову всяким бредом так и не научившись кодить
спасибо за заботу.
правда я уже староват для таких советов.
DrOffset
6459 / 3833 / 885
Регистрация: 30.01.2014
Сообщений: 6,628
01.08.2015, 17:47     Как обратится к обьекту класса, являющегося наследником абстрактного класса #89
Цитата Сообщение от Avazart Посмотреть сообщение
А я о чем... твой код бред .. непонятно что делает, для чего и как.
Класс Base пустой.... явно чего то нехватает...
Ну добавь туда что-нибудь
А вообще, все уже было сказано, повторяться не буду. Читай еще раз сначала.

Добавлено через 2 минуты
Цитата Сообщение от smartpointer Посмотреть сообщение
Это называется как загнать себя в угол с инкапсуляцией.
Нет, это называется ограничение на использование. Когда класс запрещают копировать - делают это по той же причине. Ограничивают использование. А нужно это оказалось настолько, что в новой редакции языка добавили возможность делать это из коробки.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,629
Записей в блоге: 17
01.08.2015, 17:59     Как обратится к обьекту класса, являющегося наследником абстрактного класса #90
Цитата Сообщение от DrOffset Посмотреть сообщение
Читай еще раз сначала.
Да я код читаю, из него ничего не понять что вы хотели продемонстировать... пример фиг знает чего, ради не знаю чего.

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

Вспомогательное
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
#include <QCoreApplication>
#include <algorithm>
#include <iostream>
#include <functional>
#include <vector>
#include <cassert>
 
class NonCopyable
{
   protected:
    NonCopyable() {}
    ~NonCopyable() {}
  private:
    NonCopyable( const NonCopyable& );
    NonCopyable& operator=( const NonCopyable& );
};
 
template<typename P>
struct Deleter
{
   void operator()(P p){ delete p; }
};
 
template<typename C>
inline void deleteAll(const C& c)
{
  std::for_each( c.begin(),c.end(),
                 Deleter<typename C::value_type>() );
}
 
template<typename C>
inline void findAndErase(C& c,typename C::value_type v)
{
  c.erase( std::find(c.begin(),c.end(),v) );
}


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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
class Graph;
class Vertex;
class Edge;
 
typedef std::vector<Vertex*> VContainer;
typedef std::vector<Edge*>   EContainer;
 
class DependencyManager
{
     friend class Graph;
     friend class Vertex;
     friend class Edge;
 
   private:
     static Vertex* createVertex(Graph* graph);
     static void destroyVertex(Vertex* vertex);
 
     static Edge* createEdge(Graph* graph,Vertex* from,Vertex* to);
     static void  destroyEdge(Edge* edge);
 
     static void clear(Graph* graph);
};
//----------------- Graph ------------------------------------
class Graph: private NonCopyable
{
     friend class DependencyManager;
   public:
     Graph();
     virtual ~Graph();
 
     const VContainer& vertices() const { return vertices_; }
     const EContainer& edges()    const { return edges_; }
 
     Vertex* addVertex();
     Edge*   addEdge(Vertex* from,Vertex* to);
     void clear();
 
   private:
     VContainer vertices_;
     EContainer edges_;
     bool clearMode_;
};
 
Graph::Graph():NonCopyable(),clearMode_(false)
{
 
}
 
Graph::~Graph()
{
   clear();
}
 
Vertex *Graph::addVertex()
{
   return DependencyManager::createVertex(this);
}
 
Edge *Graph::addEdge(Vertex *from, Vertex *to)
{
   return DependencyManager::createEdge(this,from,to);
}
 
void Graph::clear()
{
   DependencyManager::clear(this);
}
//------------------- Vertex ------------------------------------
class Vertex: private NonCopyable
{
    friend class DependencyManager;
  public:
    virtual ~Vertex();
 
    const EContainer& inEdges() const{ return inEdges_;  }
    const EContainer& outEdges()const{ return outEdges_; }
 
    Graph* graph()const{ return graph_; }
 
  private:
    Vertex(Graph* graph):graph_(graph){}
 
    Graph* graph_;
    EContainer inEdges_;
    EContainer outEdges_;
};
 
Vertex::~Vertex()
{
  DependencyManager::destroyVertex(this);
  std::cout<<"~Vertex()"<<std::endl;
}
//------------------- Edge ------------------------------------
class Edge: private NonCopyable
{
     friend class DependencyManager;
   public:
     virtual ~Edge();
     Vertex* from()const { return from_; }
     Vertex* to()  const { return to_; }
 
     Graph* graph()const{ return graph_; }
 
   private:
     Edge(Graph* graph,Vertex* from,Vertex* to);
 
     Graph* graph_;
     Vertex* from_;
     Vertex* to_;
};
 
Edge::Edge(Graph *graph, Vertex *from, Vertex *to)
  :NonCopyable(),graph_(graph),from_(from),to_(to)
{
 
}
 
Edge::~Edge()
{
    DependencyManager::destroyEdge(this);
    std::cout<<"~Edge()"<<std::endl;
}
//------------------- DependencyManager ------------------------
Vertex *DependencyManager::createVertex(Graph *graph)
{
  assert(graph);
  Vertex* vertex= new Vertex(graph);
  graph->vertices_.push_back(vertex);
  return vertex;
}
 
Edge *DependencyManager::createEdge(Graph *graph, Vertex *from, Vertex *to)
{
   assert(graph && from!=to && graph==from->graph_ && graph==to->graph_);
   Edge* edge= new Edge(graph,from,to);
   graph->edges_.push_back(edge);
   from->outEdges_.push_back(edge);
   to->inEdges_.push_back(edge);
   return edge;
}
 
void DependencyManager::destroyVertex(Vertex *vertex)
{
  assert(vertex);
  if(!vertex->graph_->clearMode_)
  {
    findAndErase(vertex->graph_->vertices_,vertex);
    deleteAll(vertex->inEdges_);
    deleteAll(vertex->outEdges_);
    vertex->inEdges_.clear();
    vertex->outEdges_.clear();
  }
}
 
void DependencyManager::destroyEdge(Edge *edge)
{
  assert(edge);
  if(!edge->graph_->clearMode_)
  {
    findAndErase(edge->graph_->edges_,edge);
    findAndErase(edge->from_->outEdges_,edge);
    findAndErase(edge->to_->inEdges_,edge);
  }
}
 
void DependencyManager::clear(Graph *graph)
{
  assert(graph);
  graph->clearMode_= true;
 
  deleteAll(graph->vertices_);
  deleteAll(graph->edges_);
 
  graph->vertices_.clear();
  graph->edges_.clear();
 
  graph->clearMode_= false;
}
 
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
 
    Graph g;
    Vertex* v1= g.addVertex();
    Vertex* v2= g.addVertex();
 
    Edge* e= g.addEdge(v1,v2);
 
    delete v1;
 
    return a.exec();
}
Думаю из кода понятно что попытка смоделировать граф/ребра/вершины.
DrOffset
6459 / 3833 / 885
Регистрация: 30.01.2014
Сообщений: 6,628
01.08.2015, 18:10     Как обратится к обьекту класса, являющегося наследником абстрактного класса #91
Цитата Сообщение от Avazart Посмотреть сообщение
Да я код читаю, из него ничего не понять что вы хотели продемонстировать... пример фиг знает чего, ради не знаю чего.
Там еще текст был. И этот текст связан причинно-следственной связью с предыдущим обсуждением и конкретно твоими словами об ограничении на доступ для friend конкретных полей или функций:
Цитата Сообщение от Avazart Посмотреть сообщение
friend Chain for CarGusStation::CarGusStation();
Этот пример поясняет логику, которая применяется для friend. Показывает что из себя friend представляет. Потому что попытка задуматься о таком, как в цитате выше, показывает, что ты неправильно понимаешь назначение friend в языке. Ты его воспринимаешь как "раскрывашку" данных кому не попадя, когда на самом деле это всего-лишь дополнительный способ описания интерфейсов. А неправильное применение как раз вытекает из понимания friend как простой раскрывашки данных. Если мы начнем относится к friend функциям\классам как к части интерфейса, то все станет на свои места.
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
01.08.2015, 18:52     Как обратится к обьекту класса, являющегося наследником абстрактного класса #92
Цитата Сообщение от Avazart Посмотреть сообщение
Да я код читаю, из него ничего не понять что вы хотели продемонстировать... пример фиг знает чего, ради не знаю чего.
там в обоих случаях дизайн принципиально не отличается.
различие лишь в незначительных технических деталях:

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
47
48
49
50
#include <iostream>
#include <memory>
 
// --- найдите 10 принципиальных отличий
 
class Base {};
 
 
class C1 : public Base
{
public:
    static std::unique_ptr<C1> create()
    {
        std::unique_ptr<C1> x(new C1);
        x->v = 10;
        return x;
    }
    
private:
    C1() {}
    int v;
};
 
class C2 : public Base
{
public:
    friend std::unique_ptr<C2> create();
   
private:
    C2() {}
    
    int v;
};
std::unique_ptr<C2> create()
{
    std::unique_ptr<C2> x(new C2);
    x->v = 10;
    return x;
}
 
 
 
int main()
{
    std::cout << "Hello, world!\n";
    
    // --- смотреть на дизайн использования:
    auto obj1 = C1::create();
    auto obj2 = create();
}
в обоих случаях, создание объекта в обход фабрики запрещен.
в обоих случаях, в качестве фабрики использованы свободные функции.
в обоих случаях они - часть интерфейса класса

единственная разница в том,
что статическая-функция член существует в пространстве имени своего класса

а функция друг - вне пространства имени класса.

никаких других отличий в данном случае нет вообще.

господин DrOffset, безуспешно пытается донести до вас,
что друг класса - это на самом деле такая же полноценная, и полноправная часть класса,
как и другие его части.

недаром, что функцию член можно определить прямо в теле декларации класса:

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
47
48
49
50
51
52
53
#include <iostream>
#include <memory>
 
// --- найдите 10 принципиальных отличий
 
class Base {};
 
 
class C1 : public Base
{
public:
    static std::unique_ptr<C1> create()
    {
        std::unique_ptr<C1> x(new C1);
        x->v = 10;
        return x;
    }
    
private:
    C1() {}
    int v;
};
 
class C2 : public Base
{
public:
    friend std::unique_ptr<C2> create()
    {
        std::unique_ptr<C2> x(new C2);
        x->v = 10;
        return x;
    }
 
   
private:
    C2() {}
    
    int v;
};
std::unique_ptr<C2> create();
 
 
int main()
{
    std::cout << "Hello, world!\n";
    
    // --- смотреть на дизайн использования:
    
    auto obj1 = C1::create();
    
    auto obj2 = create();
    
}

однако поскольку, часто френдами злоупотребляют,
сливая потроха кому ни поподя,
нарушая инкапсуляцию,
и превращая таким образом код в лапшу,
то это и породило миф якобы о том,
что френды - зло, и нарушают инкапсуляцию.

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

и есть манагер, в который вынесена вся логика организации связей.

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

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

однако, я противник подобного дизайна:
C++
1
2
3
4
5
6
7
    Graph g;
    Vertex* v1= g.addVertex();
    Vertex* v2= g.addVertex();
 
    Edge* e= g.addEdge(v1,v2); //<--- закатали указатель
 
    delete v1; //ой, а чего это мы тут прибили ненароком?
C++
1
2
3
4
5
6
7
8
9
Edge *DependencyManager::createEdge(Graph *graph, Vertex *from, Vertex *to)
{
   assert(graph && from!=to && graph==from->graph_ && graph==to->graph_);
   Edge* edge= new Edge(graph,from,to);
   graph->edges_.push_back(edge);
   from->outEdges_.push_back(edge);   //<--- вах! вах!!! 
   to->inEdges_.push_back(edge);
   return edge;
}
нарушение правила:
кто захватывал, тот и должен освобождать.

я за то, что бы не использовать указатели там,
где по смыслу ожидаются живые объекты.

C++
1
2
3
4
5
    
    Graph g;
    Vertex& v1= g.addVertex();
    Vertex& v2= g.addVertex();
    g.addEdge(v1,v2);
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,629
Записей в блоге: 17
01.08.2015, 19:01     Как обратится к обьекту класса, являющегося наследником абстрактного класса #93
Цитата Сообщение от hoggy Посмотреть сообщение
нарушение правила:
кто захватывал, тот и должен освобождать.
Так в том то и дело что нет явного владельца. Ибо логично что ребро не может сущетвовать отдельно от графа и от двух вершин которые оно соединяет.
Касательно указателя указателя так так и должно быть, указатель в обычных случаях может стать невалидным (Удаляем "родителя" удаляются "дочки", в данном случае у ребра два родителя, а с учетом графа - три)
irises
 Аватар для irises
68 / 25 / 8
Регистрация: 29.06.2015
Сообщений: 101
01.08.2015, 19:02  [ТС]     Как обратится к обьекту класса, являющегося наследником абстрактного класса #94
Цитата Сообщение от Mr.X Посмотреть сообщение
А зачем вам абстрактная заправка понадобилась? Это в задании так или вы сами придумали?
это такое задание

Создать консольное приложение, в котором реализовать работу сети автозаправок.
Заправки есть двух видов:
- Для легковых авто;
- Для грузовых авто.
Каждая заправка работает с тремя видами топлива: "А-92", "А-95", "А-98". Каждая заправка имеет ограниченный объем резервуара для хранения каждого вида топлива.
Функциональность сети:
1. Поставка топлива (отдельного вида отдельного заправку). Фиксируется дата поставки.
2. Отгрузка топлива (отдельного вида с отдельной заправки). Фиксируется дата отгрузки.
3. Просмотр статистики по каждой заправке: сколько запасов по видам топлива, история отгрузки пиломатериал по датам.
Все данные по запасам хранятся в файле.
Все данные по истории отгрузки хранятся в файле (другому).
4. Отчет по количеству отгруженного топлива (без деления по видам) по каждой заправке на конкретную дату (дата вводится пользователем). Определение заправки с максимальным показателем по отгрузке на конкретную дату (без деления по видам).

Реализовать абстрактный класс "Заправка". От него унаследовать два класса, которые представляют два вида заправок.
Реализовать класс "Сеть заправок".
Реализовать класс "Топливо".
Реализовать класс "Дата".
Реализовать обработку исключительных ситуциаций: попытки залить топлива больше, чем можно хранить, попытки отгрузить горючего больше, чем есть на заправке (по видам топлива).
Использовать библиотеку STL.
Проект должен быть разбит на header и cpp файлы. Каждый класс в отдельном файле.
Метод main () в отдельном файле.
Все данные загружать из файла.
Работу программы организовать в виде эргономичного меню.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,629
Записей в блоге: 17
01.08.2015, 19:15     Как обратится к обьекту класса, являющегося наследником абстрактного класса #95
hoggy, Я с этой специально и привел пример с сильносвязными объектами.

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

Добавлено через 3 минуты
Цитата Сообщение от DrOffset Посмотреть сообщение
Ты его воспринимаешь как "раскрывашку" данных кому не попадя, когда на самом деле это всего-лишь дополнительный способ описания интерфейсов.
В этом и проблема что как раз четко описать/зафиксировать интерфейс общенния/связей в нужной мере для двух и более классов нет возможностей.

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
я за то, что бы не использовать указатели там,
где по смыслу ожидаются живые объекты.
Ну так чет не уловил, в чем суть замены указателей ссылками?
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
01.08.2015, 19:45     Как обратится к обьекту класса, являющегося наследником абстрактного класса #96
Цитата Сообщение от Avazart Посмотреть сообщение
Ну полноценной она вряд ли может быть (хотя бы из выноса из пространства имен) и даже так, а как тогда трактовать дружественный класс?
ну вот взять например, итератор:
C++
1
сontainer::iterator it = cont.begin();
формально - это отдельный класс от контейнера.
но логически (и на практике) - это часть интерфейса самого контейнера.

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

например, никто не сделает ничайно delete ссылке,
которую вернула функция.

и у пользователя не возникнет сомнений
касательно прав владения ресурсом.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,629
Записей в блоге: 17
01.08.2015, 20:08     Как обратится к обьекту класса, являющегося наследником абстрактного класса #97
Цитата Сообщение от hoggy Посмотреть сообщение
но логически (и на практике) - это часть интерфейса самого контейнера.
Нет это не так.
Это прослойка/интерфейс между контейнерами и алгоритмами. Т.е нечто то что смещенно в сторону алгоритмов.
Само по себе существование итератора в отрыве от алгоритмов - нелепо. Как к примеру и friend оператор.
friend это такие себе "мостики" между несколькими "сущностями".

И пример DrOffset с использованием friend мне не понятен, мне кажется это необоснованным тем более кода есть альтернатива со статическим методом.
Да смысла в том что запрещать использования создания через конструктор я не уловил.
Только для запрета копирования? Так есть для этого прием NonCopyable причем которые не запрещает создавать объекты "не динамически".

Если подразумевалась фабрика/фабричный метод, так там по сути несколько классов, т.е дружественность на своем месте, месте "посредника". Хотя там и без дружественности вероятно можно обойтись...
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
01.08.2015, 20:13     Как обратится к обьекту класса, являющегося наследником абстрактного класса #98
Цитата Сообщение от Avazart Посмотреть сообщение
Так в том то и дело что нет явного владельца. Ибо логично что ребро не может сущетвовать отдельно от графа и от двух вершин которые оно соединяет.
Касательно указателя указателя так так и должно быть, указатель в обычных случаях может стать невалидным (Удаляем "родителя" удаляются "дочки", в данном случае у ребра два родителя, а с учетом графа - три)
владелец - граф.
который является контейнером для всех этих ребер и вершин.

он создает вершины/ребра.
он и должен их прибивать.

обратите внимание:
C++
1
Vertex(Graph* graph):graph_(graph){}
C++
1
Edge(Graph* graph,Vertex* from,Vertex* to);
элементы контейнера не самостоятельны.
они в принципе не могут существовать отдельно от своего графа.

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

наружу, как и любой другой нормальный контейнер,
граф выдает только ссылки на свои элементы.

и никто снаружи по этим ссылкам не должен их прибивать.
хорошая новость в том, что delete ссылкам не делают.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,629
Записей в блоге: 17
01.08.2015, 20:22     Как обратится к обьекту класса, являющегося наследником абстрактного класса #99
Ок тогда как вы предполагаете убивать Vertex и Edge если не через delete ?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.08.2015, 20:27     Как обратится к обьекту класса, являющегося наследником абстрактного класса
Еще ссылки по теме:

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

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

Или воспользуйтесь поиском по форуму:
hoggy
5230 / 2121 / 404
Регистрация: 15.11.2014
Сообщений: 4,812
Завершенные тесты: 1
01.08.2015, 20:27     Как обратится к обьекту класса, являющегося наследником абстрактного класса #100
Цитата Сообщение от Avazart Посмотреть сообщение
Это прослойка/интерфейс между контейнерами и алгоритмами. Т.е нечто то что смещенно в сторону алгоритмов.
забудьте на минуту слово "алгоритм".
оно вам только глаз замыливает.


есть контейнер.
и есть вызывающая сторона.
которая может выполнять манипуляции над контейнером.

все действия над контейнером осуществляются
посредством его интерфейса.

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

это можно сделать, дернув напрямую функцию-член.
или дернув итератор.


а в том что касается алгоритмов:

в итераторы вынесли нечто общее для всех контейнеров.
и стандартизировали.

то есть, алгоритмы тупо закладываются на интерфейс контейнеров.

Цитата Сообщение от Avazart Посмотреть сообщение
И пример DrOffset с использованием friend мне не понятен
я уже не знаю, как вам ещё помочь это понять.

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

в дизайне от этого ровным счетом вообще ничего не изменилось.
это два разных способа, которые делают одно и тоже действие.

Цитата Сообщение от Avazart Посмотреть сообщение
Да смысла в том что запрещать использования создания через конструктор я не уловил.
а это вообще не существенно для примера-иллюстрации.

Добавлено через 54 секунды
Цитата Сообщение от Avazart Посмотреть сообщение
Ок тогда как вы предполагаете убивать Vertex и Edge если не через delete ?
так же как и создавались - через граф.
Yandex
Объявления
01.08.2015, 20:27     Как обратится к обьекту класса, являющегося наследником абстрактного класса
Ответ Создать тему
Опции темы

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