Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Rengen
3 / 3 / 0
Регистрация: 15.01.2012
Сообщений: 67
#1

Сложности с построением многофайлового решения - C++

26.03.2014, 20:33. Просмотров 639. Ответов 26
Метки нет (Все метки)

Есть 3-и класса. Каждый в файле. Не смотрите что реализация в h-ке, это просто чтобы было проще и удобнее понимать. Ошибка построения в итоге такая же, если даже разделить объявление и определение. Все это дело не строиться. Лучше приведу код.

SubscribersList
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
 
#include "SystemBase.h"
#include "Entity.h"
 
namespace Engine {
 
    class SubscribersList {
        friend SystemBase;
 
    public:
        SubscribersList() { }
 
        void f(Entity* e) { }
    };
}
Entity.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#pragma once
 
#include "SystemBase.h"
 
namespace Engine {
 
    class Entity {
    public:
        Entity() { }
 
        void s(SystemBase* sb) { }
    };
 
}
SystemBase
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma once
#include "SubscribersList.h"
#include "Entity.h"
 
namespace Engine {
 
    class SystemBase {
    public:
        SystemBase() { }
 
        void g(Entity* e) { }
 
    private:
        SubscribersList m;
 
    };
}
Некоторые условия изменения кода если кто будет менять. После friend слово class не ставить, ибо он уже был описан и подключен соответствующим файлом. Должно работать так. Если убрать все упоминания про Entity, то как раз так и работает.
Это все билдится если
1 Затолкать в один файл.
2 Перед неопределенными для компилятора типами (Entity, SystemBase) поставить class. Однако все потом опять валится как только пытаешься вынести реализацию в cpp.
VS 2010.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.03.2014, 20:33
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Сложности с построением многофайлового решения (C++):

Работа многофайлового проекта - C++
С++ позволяет создавать многофайловые проект. Это повышает производительность, так как программа стает модульной и ее легко изменить и тд....

Компиляция и сборка многофайлового проекта - C++
Допустим, у меня есть такие файлы. SuperClass h - объявление, SuperClass cpp - реализация SubClass h - объявление, SubClass cpp -...

Создание многофайлового проекта в Borland 5.02 - C++
Кто знает как создать многофайловый проект в среде Borland 5.02

Сборка многофайлового приложения: ошибка LNK2005 - C++
Привет! Помогите пожалуйста разобраться со организацией исходников. Структура такова: ColorButton.h в нем подключается Object.h и...

Как разобраться со сборкой многофайлового проекта - C++
В теории я считал что понимаю как происходят подключения файлов, их сборка (те работа линковщика, компоновщика...) Но вот на практике это...

Ошибка при компиляции многофайлового проекта - C++
Добрый вечер. Возникает ошибка при компиляции проекта, состоящего из 3-х файлов. В программе использованы структуры и списки. Файл...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.03.2014, 20:57 #2
В классе, где есть указатель на другой класс, не нужно инклуд делать с этим классом, достаточно написать (например):
C++
1
class Entity;
ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
26.03.2014, 21:02 #3
Цитата Сообщение от Rengen Посмотреть сообщение
Перед неопределенными для компилятора типами (Entity, SystemBase) поставить class. Однако все потом опять валится как только пытаешься вынести реализацию в cpp.
а как ты добавляешь файлы в проект?
Rengen
3 / 3 / 0
Регистрация: 15.01.2012
Сообщений: 67
26.03.2014, 21:38  [ТС] #4
Цитата Сообщение от alsav22 Посмотреть сообщение
В классе, где есть указатель на другой класс, не нужно инклуд делать с этим классом, достаточно написать (например):
Код C++
1
class Entity;
Да. Я знаю. Я это вторым пуктом написал как сбилдить. Но хочется решить эту проблему иначе. Без использования слова class, но зато инклюдом его описания.

Добавлено через 1 минуту
Цитата Сообщение от ValeryS Посмотреть сообщение
а как ты добавляешь файлы в проект?
Правая кнопка на проекте -> Добавить -> Создать элемент. Ну или если уже существует Добавить существующий элемент.

Добавлено через 6 минут
Что-то я сглупил и не вывесил отчет компиляции. Хотя он ничего внятного в этих случаях не говорит.

1> main.cpp
1>f:\my\projects 3ds, autocad and other\c++\eeee2\eeee2\entity.h(11): error C2061: синтаксическая ошибка: идентификатор "SystemBase"
1>f:\my\projects 3ds, autocad and other\c++\eeee2\eeee2\subscriberslist.h(9): error C2433: Engine::SystemBase: "friend" не разрешается для объявлений данных
1>f:\my\projects 3ds, autocad and other\c++\eeee2\eeee2\subscriberslist.h(9): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
1>f:\my\projects 3ds, autocad and other\c++\eeee2\eeee2\main.cpp(10): error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "b"
1>f:\my\projects 3ds, autocad and other\c++\eeee2\eeee2\main.cpp(10): error C2065: b: необъявленный идентификатор
1> Entity.h
1>f:\my\projects 3ds, autocad and other\c++\eeee2\eeee2\entity.h(11): error C2061: синтаксическая ошибка: идентификатор "SystemBase"
1>f:\my\projects 3ds, autocad and other\c++\eeee2\eeee2\subscriberslist.h(9): error C2433: Engine::SystemBase: "friend" не разрешается для объявлений данных
1>f:\my\projects 3ds, autocad and other\c++\eeee2\eeee2\subscriberslist.h(9): error C4430: отсутствует спецификатор типа - предполагается int. Примечание. C++ не поддерживает int по умолчанию
1>f:\my\projects 3ds, autocad and other\c++\eeee2\eeee2\entity.h(7): error C2011: Engine::Entity: переопределение типа "class"
1> f:\my\projects 3ds, autocad and other\c++\eeee2\eeee2\entity.h(7): см. объявление "Engine::Entity"

И тогда main чтобы избавится от ищите в main.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
using namespace std;
 
 
#include "SystemBase.h"
using namespace Engine;
 
int main()
{
    SystemBase b;
    cin.get();
    return 0;
}
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.03.2014, 21:48 #5
Цитата Сообщение от Rengen Посмотреть сообщение
Но хочется решить эту проблему иначе.
Хотеть, конечно, можно... Но зачем иначе? Чем предложенный способ не устраивает?
Rengen
3 / 3 / 0
Регистрация: 15.01.2012
Сообщений: 67
26.03.2014, 22:11  [ТС] #6
Цитата Сообщение от alsav22 Посмотреть сообщение
Хотеть, конечно, можно... Но зачем иначе? Чем предложенный способ не устраивает?
Действительно... Я таким способом не пользовался практически, разве что в пределах одного файла. Из-за этого я не могу полностью сейчас понять к чему приведет множество прототипов классов и 0 инклудов.
Такой способ вообще распространен? Им пользуются в больших проектах? Я просто еще нигде не видел, чтобы эту проблему решали именно так. Зачем еще раз писать прототип класса, если он есть в хедере в полном объеме? Вот. Разъясните пожалуйста.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.03.2014, 22:19 #7
Цитата Сообщение от Rengen Посмотреть сообщение
Зачем еще раз писать прототип класса, если он есть в хедере в полном объеме? Вот. Разъясните пожалуйста.
А где я написал, что нужно писать и то, и то?
Цитата Сообщение от alsav22 Посмотреть сообщение
В классе, где есть указатель на другой класс, не нужно инклуд делать с этим классом, достаточно написать (например):
Касается только случая с указателем, если объект другого класса (а не указатель), то уже нужно весь хедер подключать (компилятору уже нужно будет видеть конструктор). Я не вижу всего проекта, но есть предположение, что присутствуют взаимные включения. В одном хедере подключен другой, а в том - этот. Способ с форвард-декларацией класса, как раз для таких случаев.
ValeryS
Модератор
6556 / 5022 / 464
Регистрация: 14.02.2011
Сообщений: 16,763
26.03.2014, 22:22 #8
Цитата Сообщение от Rengen Посмотреть сообщение
Зачем еще раз писать прототип класса, если он есть в хедере в полном объеме? Вот. Разъясните пожалуйста.
самый распространенный косяк
класс А ссылается на класс Б а класс Б ссылается на класс А подключение инклюдов ведет к рекрусивному подключению и соответственно к невозможности компиляции
вот обсуждалось
При #include "BasicObject.h" в Universe.h начинают вылезать ошибки
Rengen
3 / 3 / 0
Регистрация: 15.01.2012
Сообщений: 67
26.03.2014, 22:28  [ТС] #9
Цитата Сообщение от ValeryS Посмотреть сообщение
самый распространенный косяк
класс А ссылается на класс Б а класс Б ссылается на класс А подключение инклюдов ведет к рекрусивному подключению и соответственно к невозможности компиляции
вот обсуждалось
Эту проблему решает #pragma once, которая есть.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.03.2014, 22:30 #10
Цитата Сообщение от Rengen Посмотреть сообщение
Эту проблему решает #pragma once, которая есть.
В том-то и дело, что не решает.
Rengen
3 / 3 / 0
Регистрация: 15.01.2012
Сообщений: 67
26.03.2014, 22:31  [ТС] #11
Цитата Сообщение от alsav22 Посмотреть сообщение
Касается только случая с указателем, если объект другого класса (а не указатель), то уже нужно весь хедер подключать (компилятору уже нужно будет видеть конструктор). Я не вижу всего проекта, но есть предположение, что присутствуют взаимные включения. В одном хедере подключен другой, а в том - этот. Способ с форвард-декларацией класса, как раз для таких случаев.
То есть использовать forward declaration? Единственный способ? Мне почему-то при написании чего-либо всегда кажется, что все должно быть еще проще, чем я делаю.

Добавлено через 57 секунд
Цитата Сообщение от alsav22 Посмотреть сообщение
В том-то и дело, что не решает.
Как нет, если да. Я специально написал два файла со взаимным включением и все отлично сбилдилось.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.03.2014, 22:32 #12
Цитата Сообщение от Rengen Посмотреть сообщение
Я специально написал два файла со взаимным включением и все отлично сбилдилось.
Покажите код.
Rengen
3 / 3 / 0
Регистрация: 15.01.2012
Сообщений: 67
26.03.2014, 22:46  [ТС] #13
Цитата Сообщение от alsav22 Посмотреть сообщение
Покажите код.
Я сейчас восстанавливал что писал... Перечитал что мне написали. И писал я немного не то. Я написал два включающихся файлов с классами, и два файла включались друг в друга, однако классы не ссылались друг на друга и тут я понял что был не прав. Теперь ясно.

Добавлено через 1 минуту
Теперь вопрос следующий. Это работает для случая с указателями. Что делать если внутри класса объект класса? Похоже это нельзя делать, ибо размеры класса неопределенны тогда.
alsav22
5417 / 4813 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
26.03.2014, 22:48 #14
Это какой, по счёту, вопрос?
Rengen
3 / 3 / 0
Регистрация: 15.01.2012
Сообщений: 67
26.03.2014, 23:01  [ТС] #15
Цитата Сообщение от alsav22 Посмотреть сообщение
Это какой, по счёту, вопрос?
Лучше что они есть, чем если бы я делал проекты чужими силами за счет своих материальными средствами)
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.03.2014, 23:01
Привет! Вот еще темы с ответами:

Беда с наследованием. Организация многофайлового приложения - C++
Вот написал такое вот чудо, работает если за коментировать любой из #include &quot;kvadrat.h&quot; #include &quot;kolo.h&quot; и соотвецтвенно их исполнения....

Компиляция многофайлового проекта: Unexpected end of file while looking for precompiled header - C++
Здравствуйте! Почему когда компилирую такой проект: testHeader.h #ifndef _TEST_HEADER_H_ #define _TEST_HEADER_H_ int...

совсем запуталась с построением( - C++
Составьте блок-схему алгоритма решения задачи, а также запишите словесно-пошаговый алгоритм (псевдокод): можно ли построить треугольник с...

Метод вращений с построением КЮЭР-разложения - C++
Я написал только Метод вращения #include&lt;math.h&gt; #include&lt;stdio.h&gt; #include&lt;stdlib.h&gt; #include&lt;time.h&gt; void f(double *mass,...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
26.03.2014, 23:01
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru