Я делаю многофайловый проект на C ++. У меня есть этот код:

Lista.h

struct elem
{
    account info;
    elem* next;
};

typedef elem* lista;

Ошибка показана здесь, где объявлено «lista * a».

Login.h :

struct account
{
    string user = "";
    int hash_pass = 0;
};

struct list
{
   lista* a;
   int size;
};

Login.cc :

#include "login.h"
#include "lista.h"
....

Lista.cc

#include "login.h"
#include "lista.h"
....

В lista.cc и login.cc я включил login.h и lista.h, но в login.h не распознает lista как имя типа.

c++
0
Interseba5 20 Авг 2018 в 11:48

4 ответа

Лучший ответ

Круговая зависимость! Предполагая, что тип string четко определен где-то еще в заголовочных файлах (возможно, std::string?), это потому, что вы включили файлы в неправильном порядке.

#include "login.h"
#include "lista.h" 
....

Это в основном эквивалентно:

struct account
{
    string user = "";
    int hash_pass = 0;
};

struct list
{
   lista* a;
   int size;
};

struct elem
{
    account info;
    elem* next;
};

typedef elem* lista;
....

Как видите, lista появляется еще до typedef, поэтому вы получаете ошибку.

Очевидно, вам не нужно заботиться о том, в каком порядке вы включаете файлы заголовков, поэтому правильное решение здесь будет включать lista.h в login.h с надлежащими средствами защиты заголовков. Но этого недостаточно в этом случае : здесь есть круговая зависимость, поскольку lista.h нуждается в struct account от login.h и login.h нуждается в {{ X6}} из lista.h. Поэтому мы также добавляем предварительную декларацию. Для получения дополнительной информации см. эту ссылку. Ваш окончательный код будет:

lista.h :

#ifndef LISTA_H_
#define LISTA_H_
struct account; // forward declaration

struct elem
{
    account* info; // notice that `account` now has to be a pointer
    elem* next;
};

typedef elem* lista;
#endif

login.h:

#ifndef LOGIN_H_
#define LOGIN_H_
#include "lista.h"

struct account
{
    string user = "";
    int hash_pass = 0;
};

struct list
{
   lista* a;
   int size;
};
#endif
2
HSK 20 Авг 2018 в 09:21

Если вы хотите использовать что-то объявленное в A.h внутри B.h, вам нужно включить A.h в B.h. Следовательно, необходимо включить lista.h в login.h.

1
Ricardo Costeira 20 Авг 2018 в 08:55

Ваша проблема сводится к следующему:

struct elem
{
  account info;   // <<< account is not known here
  elem* next;     // elem is not known here
};

typedef elem* lista;   

struct account
{
  std::string user = "";
  int hash_pass = 0;
};

struct list
{
  lista* a;
  int size;
};    

typedef elem* lista;

Если вы исправите порядок объявлений, он будет хорошо скомпилирован:

struct account
{
  std::string user = "";
  int hash_pass = 0;
};

struct elem
{
  account info;
  elem* next;
};

typedef elem* lista;

struct list
{
  lista* a;
  int size;
};
0
Jabberwocky 20 Авг 2018 в 09:02

Включите lista.h в login.h, так как вам нужен заголовок для входа в lista :)

0
Prodigle 20 Авг 2018 в 09:01
51927142