Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
5 / 5 / 1
Регистрация: 21.02.2019
Сообщений: 38

Компиляция нескольких файлов со структурами C++

21.02.2019, 18:48. Показов 2473. Ответов 2

Студворк — интернет-сервис помощи студентам
Доброго времени суток! Начал работать с разделением программы на файлы и, как следовало ожидать, наткнулся на ошибки.

Реализованы структуры для описания выражений (Expression - чисто виртуальный класс, Number содержит число, BinaryOperation - содержит операцию и оба операнда) Number и BinaryOperation унаследованы от Expression. Также реализован шаблон проектирования посетитель: Visitor - чисто виртуальный класс и PrintVisitor - класс обеспечивающий вывод выражения, унаследован от Visitor.

Expression.h:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef EXPRESSION
#define EXPRESSION
#include "Visitor.h"
 
// Base structure to store expressions
struct Expression
{
    virtual double evaluate() const = 0;    // returns value of object
    virtual void visit(Visitor * visitor) const  = 0;   // Visitor pattern
 
    virtual ~Expression(){}
};
 
#endif // EXPRESSION
BinaryOperation.h:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#ifndef BINARYOPERATION
#define BINARYOPERATION
#include "Expression.h"
#include "Visitor.h"
 
// Structure for simple operations
struct BinaryOperation : Expression
{
    BinaryOperation(Expression const * left, char op, Expression const * right)
        : left(left), op(op), right(right)
    { }
 
    Expression const * get_left()  const;   // the left operand
    Expression const * get_right() const;   // the right operand
    char get_op() const;
    double evaluate() const{    // value of operation
        switch(op)  // op is operation symbol
        {
            case '+': return left->evaluate() + right->evaluate();
            case '-': return left->evaluate() - right->evaluate();
            case '*': return left->evaluate() * right->evaluate();
            case '/': return left->evaluate() / right->evaluate();
        }
    }
 
    virtual void visit(Visitor * visitor) const  // Visitor Pattern
    {
        visitor->visitBinaryOperation(this);
    }
 
    ~BinaryOperation(){     // numbers allocate with 'new'
        delete left;
        delete right;
    }
 
private:
    Expression const * left;    // left operand
    Expression const * right;   // right operand
    char op;    // operation symbol
};
 
#endif // BINARYOPERATION
Реализация некоторых методов из BinaryOperation(BinaryOperation.cpp):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "BinaryOperation.h"
 
Expression const * BinaryOperation::get_left()  const { return left; }
 
Expression const * BinaryOperation::get_right() const { return right; }
 
char BinaryOperation::get_op() const { return op; }
 
double BinaryOperation::evaluate() const{
    switch(op)
    {
        case '+': return left->evaluate() + right->evaluate();
        case '-': return left->evaluate() - right->evaluate();
        case '*': return left->evaluate() * right->evaluate();
        case '/': return left->evaluate() / right->evaluate();
    }
}
Number.h:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef NUMBER
#define NUMBER
#include "Expression.h"
#include "Visitor.h"
 
// Structure for numbers
 
struct Number : Expression
{
    Number(double value)
        : value(value)
    {}
 
    double evaluate() const {return value;}     // returns value of number
 
    virtual void visit(Visitor * visitor) const // Visitor pattern
    {
        visitor->visitNumber(this);
    }
private:
    double value;   // value of number
};
 
#endif // NUMBER
Visitor.h:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef VISITOR
#define VISITOR
#include "Number.h"
#include "BinaryOperation.h"
#include "Expression.h"
 
// Visitor pattern
 
struct Visitor {
    virtual void visitNumber(Number const * number) = 0;
    virtual void visitBinaryOperation(BinaryOperation const * binary) = 0;
    virtual ~Visitor() { }
};
 
#endif // VISITOR
PrintVisitor.h:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#ifndef PRINTVISITOR
#define PRINTVISITOR
#include "Visitor.h"
 
// For Visitor pattern
// prints expression
struct PrintVisitor : Visitor {
 
    // If number -> print number
    void visitNumber(Number const * number)
    {
        cout << number->evaluate();
    }
 
    /* If object is binary operation ->
     * consider operands and print operation symbol
     */
    void visitBinaryOperation(BinaryOperation const * bop)  // if
    {
        cout << '(';    // saves the order of operations
        bop->get_left()->visit(this);   // next level of recursion
        std::cout << ' ' << bop->get_op() << ' ';
        bop->get_right()->visit(this);  //next level of recursion
        cout << ')';
    }
};
 
#endif // PRINTVISITOR
main.cpp:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include "Expression.h"
#include "Number.h"
#include "BinaryOperation.h"
 
using namespace std;
 
int main()
{
    Expression* expr = new BinaryOperation(new Number(4.5), '*', new Number(7));    // create expression (4.5 * 7)
    PrintVisitor visitor;
    expr->visit(&visitor); // print expr
 
    return 0;
}
А вот ошибки.туткактут
||=== Build: Debug in Expession1 (compiler: GNU GCC Compiler) ===|
Number.h|9|error: expected class-name before '{' token|
Number.h|16|error: 'Visitor' has not been declared|

Number.h||In member function 'virtual void Number::visit(int*) const':|
Number.h|18|error: request for member 'visitNumber' in '* visitor', which is of non-class type 'int'|

BinaryOperation.h|8|error: expected class-name before '{' token|
BinaryOperation.h|9|error: expected ')' before 'const'|
BinaryOperation.h|13|error: 'Expression' does not name a type|
BinaryOperation.h|14|error: 'Expression' does not name a type|
BinaryOperation.h|26|error: 'Visitor' has not been declared|
BinaryOperation.h|37|error: 'Expression' does not name a type|
BinaryOperation.h|38|error: 'Expression' does not name a type|
BinaryOperation.h||In member function 'double BinaryOperation::evaluate() const':|
BinaryOperation.h|19|error: 'left' was not declared in this scope|
BinaryOperation.h|19|note: suggested alternative:|
note: 'std::left'| - вроде не очень важно (без этого работало в версии без Visitor)
BinaryOperation.h|19|error: 'right' was not declared in this scope|
BinaryOperation.h|19|note: suggested alternative:|
note: 'std::right'| - тоже самое

BinaryOperation.h||In member function 'virtual void BinaryOperation::visit(int*) const':|
BinaryOperation.h|28|error: request for member 'visitBinaryOperation' in '* visitor', which is of non-class type 'int'|

BinaryOperation.h||In destructor 'BinaryOperation::~BinaryOperation()':|
BinaryOperation.h|32|error: 'left' was not declared in this scope|
BinaryOperation.h|32|note: suggested alternative:|
BinaryOperation.h|33|error: 'right' was not declared in this scope|
BinaryOperation.h|33|note: suggested alternative:|

main.cpp||In function 'int main()':|
main.cpp|10|error: no matching function for call to 'BinaryOperation::BinaryOperation(Number *, char, Number*)'|

BinaryOperation.h|7|note: candidate: BinaryOperation::BinaryOperation()|
BinaryOperation.h|7|note: candidate expects 0 arguments, 3 provided|
BinaryOperation.h|7|note: candidate: constexpr BinaryOperation::BinaryOperation(const BinaryOperation&)|
BinaryOperation.h|7|note: candidate expects 1 argument, 3 provided|

main.cpp|11|error: 'PrintVisitor' was not declared in this scope|
main.cpp|12|error: 'visitor' was not declared in this scope|
||=== Build failed: 18 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

На первых парах понятно, что собака зарыта в том, что Visitor не живет без BinaryOperation и Number, а Number и BinaryOperation в свою очередь не могут без Visitor. Не знаю есть ли какой-то порядок компиляции файлов, но если он бы существовал - как его настроить?

Бьюсь уже целый день и буду очень рад помощи!
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.02.2019, 18:48
Ответы с готовыми решениями:

Компиляция нескольких файлов
Создал проект на wxDevC++ таким образом: потом создал три файла в проекте: coordin.h #ifndef COORDIN_H_ #define COORDIN_H_...

Компиляция нескольких файлов
Здравствуйте, есть программа состоящая из 4 cpp, необходимо ее собрать, попытался собрать с помощью MinGW(взял тут...

Компиляция и компоновка нескольких файлов
Добрый день уважаемые форумчане. Продолжая изучать учебник &quot;How to Prgoramm C++&quot; я наткнулся на материал, в котором описывается код, точнее...

2
Just Do It!
 Аватар для XLAT
4211 / 2668 / 655
Регистрация: 23.09.2014
Сообщений: 9,077
Записей в блоге: 3
21.02.2019, 19:21
в таких случаях помогает общее правило:
1. Скомпильте сначала хелловорд.
2. Если гуд, то добавьте туда свою базовую структуру.
3. Если гуд, то добавьте туда одного наследника.
4. Если гуд, то добавьте туда остальных наследников.
5. Если гуд, то в продакшен.
6. Если гуд, то загорать на Мали.
7. Всё.
2
3258 / 2060 / 351
Регистрация: 24.11.2012
Сообщений: 4,909
21.02.2019, 19:36
Лучший ответ Сообщение было отмечено Watsab как решение

Решение

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

Есть и другие ошибки, но с их исправлением уже не должно возникнуть проблем.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.02.2019, 19:36
Помогаю со студенческими работами здесь

компиляция нескольких файлов GCC
У меня есть 4 файлы. main.c #include &lt;stdio.h&gt; #include &quot;main.h&quot; #include &quot;file_1.h&quot; int test_value_1=111; int...

Компиляция нескольких файлов
Написать скрипт, который компилирует заданные файлы и передает на исполнение. Файлы расширения .c, компиляция командой gcc. Файлы...

Компиляция нескольких файлов
Допустим запустил такую команду: mcc -m f1.m f2.m f3.m где f1-f3 это файлы-функции. Какая из этих трех функций будет...

Компиляция из нескольких файлов класса
Господа, прошу вашей помощи. пытаюсь скомпилировать класс в котором используется другой класс. player.class успешно скомпилирован и...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия SDL 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual. . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru