Рециркуляция данных между классами в C ++ - ошибка: 'не был объявлен в этой области - PullRequest
0 голосов
/ 06 ноября 2019

Я готовлю программу с несколькими классами, которые должны впоследствии обмениваться данными в коде. Это приводит к включению классов в заголовки друг друга. Я столкнулся с проблемой, когда дело дошло до передачи вектора объектов «Gas» в метод класса «Thermal», а затем пытался передать измененный объект «Thermal» в метод класса «Gas». Я попытался включить эти классы в заголовочные файлы друг друга, но с ужасным результатом. Может быть, я сделал что-то не так с этим. Возможно, объявление указателей между объектами класса решит проблему? Я устал от этого, но, к сожалению, у меня может не быть опыта работы с указателями, так как я тоже потерпел неудачу.

Примечание. Когда я закомментирую #include "Thermal.h" из класса "Gas", кодуспешно компилируетсяОднако затем необходимо также закомментировать метод диффузии.

Компилятор возвращает следующее:

./src/Thermal.h:86:76: error: template argument 2 is invalid
./src/solution.cpp: In function 'void solution(const Ref::Reformer&, 
const std::vector<Ref::Segment>&, std::ofstream*, std::ofstream*, std::ofstream*)':
./src/solution.cpp:92:40: error: no matching function for call to 'Ref::Thermal::
conduction(const Ref::Reformer&, Ref::Grid&, std::vector<Ref::Gas>&, Ref::Velocity&)'
  T.conduction(reactor, grid, gases, vel);
                                        ^
In file included from ./src/Gas.h:20:0,
                 from ./src/solution.cpp:16:
./src/Thermal.h:86:8: note: candidate: void Ref::Thermal::conduction(const Ref::Reformer&, 
const Ref::Grid&, const int&, const Ref::Velocity&)
   void conduction(const Reformer& RE, const Grid& GD, const std::vector<Gas>& GAS, 
const Velocity& VE);
        ^
./src/Thermal.h:86:8: note:   no known conversion for argument
 3 from 'std::vector<Ref::Gas>' to 'const int&'

Вот как я вызываю методы. Объекты классов "Thermal" и "Gas" создаются в одном файле .cpp и вызываются впоследствии. Их инициализация требует построения и передачи объекта класса "Grid", что также делается в том же файле.

Создание объектов:

Grid grid(0.3, 0.052);
grid.setNX(90);
grid.setNR(15);

Thermal T(grid);
for(i = 0; i < 6; i++){                                     
    gases.push_back(Gas(i, grid));
}

Вызов методов:

 T.conduction(reactor, grid, gases, vel);
 for(int i = 0; i < gases.size(); i++){
     gases[i].diffusion(reactor, grid, vel, T);
 }

Объявление класса сетки:

#ifndef REFORMING_CODE_REF_GRID_H
#define REFORMING_CODE_REF_GRID_H

#include "../input.h"

namespace Ref{
    class Grid{
    public:
        Grid(const double& x1, const double& r1, const double& x0 = 0., const double& r0 = 0.){
            xmin_ = x0;
            xmax_ = x1;
            rmin_ = r0;
            rmax_ = r1;
        }

        void setNX(const int& nx){          //setting number of elements in the longitudinal direction 
            NX_ = nx;
            ni_ = NX_ - 1;
        }

        void setNR(const int& nr){          //setting number of elements in the radial direction
            NR_ = nr;
            nj_ = NR_ - 1;
        }
    };
}//end of namespace
#endif //REFORMING_CODE_REF_GRID_H

Объявление класса температуры:

#ifndef REFORMING_CODE_REF_THERMAL_H
#define REFORMING_CODE_REF_THERMAL_H

#include "../input.h"
#include "Reformer.h"
#include "Grid.h"
#include "Velocity.h"
#include "Gas.h"

namespace Ref{
    class Thermal{
    public:
        Thermal(const Grid& grid){
            NX_ = grid.NX();
            NR_ = grid.NR();
        }

        void conduction(const Reformer& RE, const Grid& GD, const std::vector<Gas>& GAS, const Velocity& VE);


    private:
        int NX_;                                //quantity of elements in the X direction
        int NR_;                                //quantity of elements in the R direction

        std::vector<double> val_;               //Temperature value (K)
        std::vector<double> val_old_;
        std::vector<double> s_;                 //Thermal source
    };
} //end of namespace

#endif //REFORMING_CODE_REF_THERMAL_H

Определение метода проводимости:

#include "Thermal.h"
namespace Ref{ 
    void Thermal::conduction(const Reformer& RE, const Grid& GD, 
    const std::vector<Gas>& GAS, const Velocity& VE){}
}

Объявление класса газа:

#ifndef REFORMING_CODE_REF_GAS_H
#define REFORMING_CODE_REF_GAS_H

#include "../input.h"
#include "Reformer.h"
#include "Grid.h"
#include "Velocity.h"
#include "Thermal.h"

namespace Ref{
    class Gas{
    public:
        Gas(const int id, const Grid& grid){
            id_ = id;
            NX_ = grid.NX();
            NR_ = grid.NR();
        }
        void diffusion(const Reformer&, const Grid&, const Velocity&, const Thermal&);
     private:
        int id_;                            
        int NX_;                            
        int NR_;                            
    };
} //end of namespace
#endif //REFORMING_CODE_REF_GAS_H

Определение метода диффузии:

#include "Gas.h"

namespace Ref{
    void Gas::diffusion(const Reformer& RE, const Grid& GD, 
                         const Velocity& VE, const Thermal& T){}
} //end of namespace

1 Ответ

0 голосов
/ 06 ноября 2019

Вы можете попробовать использовать предварительные объявления и переместить #include в конец заголовка. (ваш файл не будет включен дважды из-за защиты заголовка)

Пример минимальной компиляции:

//RecursiveA.h

#ifndef RECURSIVEA_H
#define RECURSIVEA_H

class RecursiveA {
    public:
        void workOnB(const class RecursiveB &);
};

#include "RecursiveB.h"

#endif // RECURSIVEA_H

//RecursiveB.h

#ifndef RECURSIVEB_H
#define RECURSIVEB_H

class RecursiveB {
    public:
        void workOnA(const class RecursiveA &);
};

#include "RecursiveA.h"

#endif // RECURSIVEB_H

//RecursiveA.cpp
#include "RecursiveA.h"

void RecursiveA::workOnB(const RecursiveB &b){

}

//RecursiveB.cpp
#include "RecursiveB.h"

void RecursiveB::workOnA(const RecursiveA &a){

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...