Файл реализации будет распознавать только предварительное объявление другого класса

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

Класс A имеет функцию "decode", которая принимает один аргумент типа B, определенный в отдельном файле. Я хотел бы сохранить все файлы .h и .cpp в виде отдельных файлов. Они здесь.

A.h:

class B;
class A{
private:
    string sentence;
public:
    A();
    void decode(const B& decoder);
};

B.h:

class B{
private:
    int code[26];
public:
    B();
    int getCode(int index);
};

A.cpp:

#include "A.h"
A::A(){}
double A::decode(const B& decoder){
    B.getCode(1);
    //other things
}

Б.цпп:

#include "B.h"

B::B(){}
int B::getCode(int index){};

и водитель:

#include "B.h"
#include "A.h"
using namespace std;
int main(int argc, char* argv[]){
    B myB;
    A myA;
    myA.decode(B);
}

Я компилирую это с помощью g++ -Wall driver.cpp B.cpp A.cpp, но получаю ошибку, которая выглядит так:

Ошибка A.cpp:4: недопустимое использование неполного типа "const class B"

Я просмотрел массу подобных тем, пытаясь найти ответ, но у меня пока ничего не получилось. Любые идеи?


person Ethan    schedule 05.02.2018    source источник
comment
Вам нужно #include "B.h" в A.cpp.   -  person R Sahu    schedule 05.02.2018
comment
#include B.h в верхней части A.h. Включайте только A.h в main,cpp. Научитесь использовать include-guards.   -  person Jive Dadson    schedule 05.02.2018


Ответы (2)


Поскольку вы используете функцию-член getCode B в файле A.cpp, одного прямого объявления будет недостаточно, поскольку в нем ничего не говорится о функциях-членах B. Должна быть доступна вся декларация B. Для этого включите заголовок "B.h" в файл A.cpp:

#include "B.h"

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

person Ron    schedule 05.02.2018

Лучшей практикой является то, что каждый файл .h включает в себя все, что ему нужно. Это означает, что A.h должен включать B.h.

A.h:

#pragma once // Or equivalent include-guard macros
#include "B.h"

class A{
private:
    string sentence;
public:
    A();
    void decode(const B& decoder);
};

B.h:

#ifndef B_h
#define B_h true
class B{
private:
    int code[26];
public:
    B();
    int getCode(int index);
};
#endif 

A.cpp:

#include "A.h"
A::A(){}
double A::decode(const B& decoder){
    B.getCode(1);
    //other things
}

Б.цпп:

#include "B.h"

B::B(){}
int B::getCode(int index){};

и водитель:

#include "A.h"

void main(){
    B myB;
    A myA;
    myA.decode(B);
}
person Jive Dadson    schedule 05.02.2018