C нет соответствующей функции для вызова ‘Nodo::Nodo()’

#c

#c

Вопрос:

Доброе утро.

Я пытаюсь реализовать график на c с узлами и ребрами, сохраненными в виде списков. Я итальянец, поэтому: график / Grafo, ребро / Arco, узел / Nodo, списки / ListaArchi, список узлов / ListaNodi.

Это мой код:

Grafo.h

 #ifndef GRAFO_H_
#define GRAFO_H_
#include "ListaNodi.h"

class Grafo {
public:
    Grafo();
    virtual ~Grafo();
    void leggiGrafo(std::string nomeFile);
    void aggiungiNodo(std::string nomeNodo);
private:
    std::string nomeGrafo;
    ListaNodi nodi;
};

#endif /* GRAFO_H_ */
  

Grafo.cpp

 #include "Grafo.h"

Grafo::Grafo() {
}

Grafo::~Grafo() {
}

void Grafo::aggiungiNodo(std::string nomeNodo) {
}

void Grafo::leggiGrafo(std::string nomeFile){
}
  

Arco.h

 #ifndef ARCO_H_
#define ARCO_H_
#include <string>
#include "Nodo.h"

class Arco {
public:
    Arco();
    virtual ~Arco();
    Arco *next;
    std::string style;
    std::string color;
private:
    Nodo primo;
    Nodo secondo;
};

#endif /* ARCO_H_ */
  

Arco.cpp (Вот в чем проблема:

Arco.cpp:10:12: ошибка: нет соответствующей функции для вызова ‘Nodo::Nodo()’

 #include "Arco.h"

Arco::Arco() {
    // TODO Auto-generated constructor stub
    next = NULL;
}

Arco::~Arco() {
    // TODO Auto-generated destructor stub
}
  

Nodo.h

Здесь другая проблема:

Nodo.h:15:2: ошибка: дополнительная квалификация ‘Nodo::’ для участника ‘Nodo’ [-fpermissive]

 #ifndef NODO_H_
#define NODO_H_
#include <string>
#include "ListaArchi.h"

class Nodo {
public:
    Nodo::Nodo(std::string nome);
    virtual ~Nodo();
    void setColore(std::string colore);
    ListaArchi listaArchi;
    Nodo *next;
private:
    std::string colore;
    std::string nome;
    std::string label;
};

#endif /* NODO_H_ */
  

Nodo.cpp

 #include "Nodo.h"
#include <string>

Nodo::Nodo(std::string nome) {
    this->nome = nome;
    this->colore = "white";
    next=NULL;
}

Nodo::~Nodo() {

}
  

Arco.h

Здесь другая проблема:

ListaArchi.h:16:2: ошибка: ‘Arco’ не называет тип

 #ifndef LISTAARCHI_H_
#define LISTAARCHI_H_
#include "Arco.h"

class ListaArchi {
public:
    ListaArchi();
    virtual ~ListaArchi();
    Arco arco;
};

#endif /* LISTAARCHI_H_ */
  

ListaArchi.cpp

 #include "ListaArchi.h"

ListaArchi::ListaArchi() {

}

ListaArchi::~ListaArchi() {

}
  

ListaNodi.h

 #ifndef LISTANODI_H_
#define LISTANODI_H_
#include "Nodo.h"

class ListaNodi {
public:
    ListaNodi();
    virtual ~ListaNodi();
    Nodo nodo;
};

#endif /* LISTANODI_H_ */
  

ListaNodi.cpp

 #include "ListaNodi.h"

ListaNodi::ListaNodi() {
    nodo = NULL;
}

ListaNodi::~ListaNodi() {

}
  

Кто-нибудь может помочь мне с этими проблемами?

Комментарии:

1. У вас нет конструктора по умолчанию для Nodo , но он требуется в другом месте (например, в ListaNodi )..

2. удалить Nodo:: внутри тела класса

3. У вас также есть циклические зависимости между вашими классами. (Это причина того, что «‘Arco’ не называет тип».) В SO есть много ответов на вопросы о том, как решить эту проблему.

4. Есть ли какая-либо причина, по которой вы хотите реализовать это, используя список узлов / дуг? Почему бы просто не сохранить их в векторах и иметь указатели на узлы в вашей дуге?

Ответ №1:

У вас есть несколько проблем. Одна из них заключается в том, что в вашем ListaNodi классе используйте Nodi class для объявления объекта nodo . При этом будет использоваться конструктор по умолчанию из Nodi , но вы его не объявили и не определили. Только конструктор, принимающий строку.

Простым решением для вышеупомянутого является создание Nodi конструктора по умолчанию, то есть конструктора, не принимающего аргументы.

Другая проблема заключается в ListaNodi реализации конструктора, где вы делаете

 nodo = NULL;
  

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

 ListaNodi::ListaNodi()
    : nodo{}
{
}
  

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

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

Однотонные

 Nodo(std::string nome);
  

это все, что вам нужно.

Наконец, у вас есть проблема с циклической зависимостью от файла заголовка, где ListaArchi зависит от Arco того, Nodo что зависит от ListaArchi того, что зависит от. от. Вам нужно найти способ разорвать этот круг зависимости от файла заголовка. Самый простой способ разорвать такой круг — где-нибудь использовать указатели и пересылать объявление типа вместо включения файла заголовка.


Кажется, что вы создаете списки, что означает, что вы можете очень легко разорвать циклическую зависимость файла заголовка, сделав «узлы» в классах списка указателями, чем они, вероятно, должны были быть с самого начала. Это фактически решит две первые проблемы, о которых я упоминал.

Тогда ListaArchi.h файл заголовка мог бы выглядеть следующим образом:

 #ifndef LISTAARCHI_H_
#define LISTAARCHI_H_

class Arco;  // Forward declaration instead of header file inclusion

class ListaArchi {
public:
    ListaArchi();
    virtual ~ListaArchi();
    Arco* arco;  // Declares as a pointer
};

#endif /* LISTAARCHI_H_ */
  

И ListaNode.h должно выглядеть так

 #ifndef LISTANODI_H_
#define LISTANODI_H_

class Nodo;  // Forward declaration instead of header file inclusion

class ListaNodi {
public:
    ListaNodi();
    virtual ~ListaNodi();
    Nodo* nodo;  // Declare as a pointer
};

#endif /* LISTANODI_H_ */
  

Наконец, ваш ListaNodi конструктор имеет больше смысла при NULL назначении, но я предлагаю вам по-прежнему использовать списки инициализаторов построения:

 ListaNodi::ListaNodi()
    : nodo{nullptr}
{
}