2015-03-01 6 views
-1

Я пытаюсь построить некоторые алгоритмы сетевого потока, и мне нужно представить ребра в графе.C++ new в аргументе функции

это мой край структура:

struct Edge{ 
    int from, to, flow, cap; 
    Edge(int fromC, int toC, int flowC , int capC) 
    : from(fromC), to(toC), flow(flowC), cap(capC) 
    {}; 
}; 

то у меня есть структура графа со списком смежности:

struct Graph { 
    int N; 
    vector<vector<Edge> > adjList; // list of neighbours  

    Graph(int n) {     // constructor 
    N=n; 
    adjList.resize(n); 
    } 
}; 

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

void addEdge (Graph &G, Edge &E) 
{ 
    G.adjList[E.from-1].push_back(E); 
} 

и я хочу использовать этот синтаксис:

Graph G = Graph(4); // creates graph with4 vertices 
addEdge(G, new Edge(2, 4, 0, 4)); 

но это Безразлично `работа ... Я должен изменить функцию:

void addEdge(Graph &G, Edge *E) 

, а затем изменить все в теле функции ...

Мой вопрос: Есть ли способ использовать новый вызов функции со ссылками как?:

addEdge(G, new Edge(2, 4, 0, 4)); 

T приветствую вас за ваши ответы. (Я новичок в C++, извините, если ответ очевиден: Нет, вы должны использовать указатели в подписи & тела ...)

+1

Почему вы хотите использовать 'new', как это? – juanchopanza

+0

, потому что в противном случае мне пришлось бы использовать «Edge e = Edge (1,3,0,4); addEdge (G, e); 'которые являются 2 строками кода или 2m строк, где m - количество строк – martinerk0

+4

Это очень плохая причина для использования динамического выделения. Что вам нужно сделать, это изменить функцию на 'void addEdge (Graph & G, const Edge & E)', а затем сказать 'addEdge (G, Edge (1, 3, 0, 4));'. – juanchopanza

ответ

2

Избавиться от new и есть addEdge приму в const Edge&. Это позволяет просто использовать автоматический временный, как это:

addEdge(G, Edge(2,4,0,4)); 

addEdge «s подпись становится void addEdge(Graph &G, const Edge &E).

+1

Как я уже сказал, это должно было быть довольно очевидным, спасибо: D – martinerk0

0

Да, вы можете написать просто:

addEdge(G, Edge(2,4,0,4)); 

Но вы должны рассмотреть проблемы с производительностью. Эта форма создает временный экземпляр в стеке, поэтому вы должны сделать копию (push_back alreade делает).

+0

_ «так что вы должны сделать копию» _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ Последнее редактирование: –

+0

Да, но он может создавать больше накладных расходов, чем обработка указателем.Это зависит от варианта использования, какой способ больше подходит для решения проблемы. – sgflt

+0

_ «Да, но он может создавать больше накладных расходов, чем обработка указателем». _ Как на самом деле? –

-1

Объявление addEdge, чтобы сделать ссылку const, так как вы не изменяете исходный объект.

Тогда вы можете просто сделать следующее:

void addEdge (Graph &G, const Edge &E) { ... } 
addEdge(G, Edge(2,4,0,4)); 

Это предпочтительный способ в C++, так как это позволяет избежать динамического распределения.

+1

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

+0

@juanchopanza Правда. Интересно, почему это так ... – emlai

+0

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