Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Проблема включения хедеров


Автор: Burka 19.6.2012, 00:01
Подскажите как решить такую проблему: у меня много мелких классов, которые могут использовать друг друга. Как правильно организовать хедеры что бы не возникало проблем при компиляции, с расчетом на будущие добавляния новых классов. 
Вот так у меня сейчас, и возникает ошибка типа 
Цитата

     error C2146: синтаксическая ошибка: отсутствие ";" перед идентификатором "MegaObject"


Action.h
Код

 #include "shared.h"

class Action 
{
   void execute(Object*, MegaObject*);
}


Object.h
Код

 #include "shared.h"
 
class Object 
{
   Action* current;
}


MegaObject.h
Код

 #include "shared.h"
 
class MegaObject: public Object{}


shared.h
Код

#include "Action.h"
#include "Object .h"
#include "MegaObject.h"


Автор: alexvs11 19.6.2012, 00:21
во-первых
http://ru.wikipedia.org/wiki/Include_guard

Автор: Burka 19.6.2012, 00:23
#pragma once мне не помогает smile

Автор: alexvs11 19.6.2012, 00:28
тогда напиши нормальный код
то что ты выложил (без include guard'ов и pragma once) точно работать не может

Автор: Burka 19.6.2012, 00:31
Нормальный код я как раз хотел увидеть) потому что у меня не работает никак)



Action.h
Код

#pragma once
#include "shared.h"

class Action 
{
   void execute(Object*, MegaObject*);
};


Object.h
Код

#pragma once
#include "shared.h"
 
class Object 
{
   Action* current;
};


MegaObject.h
Код

#pragma once
#include "shared.h"
 
class MegaObject: public Object{};


shared.h
Код

#pragma once
#include "Action.h"
#include "Object .h"
#include "MegaObject.h"

Автор: alexvs11 19.6.2012, 01:06
Burka, ; после class { }; стоят?

Автор: Burka 19.6.2012, 01:14
Поправил в примере, вообще да везде стоят, перепроверил. У меня вообще больше классов, я хотел увидеть пример какой-нибудь работающий с множеством инклудов перекрестных. Я просто чего то не допонимаю и из за этой мелочи не могу сделать

Автор: alexvs11 19.6.2012, 01:23
Код

#pragma once

class Object;
class MegaObject;

class Action 
{
   void execute(Object*, MegaObject*);
};


Код

#pragma once
#include "shared.h"
 
class MegaObject: public Object{};


Код

#pragma once
#include "shared.h"
 
class Object 
{
   Action* current;
};



Код

#pragma once
#include "Action.h"
#include "Object.h"
#include "MegaObject.h"



Код

#include "shared.h"

int main() {

}

Автор: Dem_max 19.6.2012, 08:48
не ругается на отсутствие конструкторов класса ?
тот же Builder проигнорирует отсутствие конструктора и создаст его сам по умолчанию.

Автор: Alexeis 19.6.2012, 13:21
  Очень вероятно что объекты у вас ссылаются друг на друга в виде полей. Такое поведение не запрещено, но только если поля являются указателями и присутствует опережающее описание объекта. Кроме того такая циклическая ссылочность серьезно ограничит возможности по написанию кода в заголовках. Некоторые послабления есть для шаблонов, ввиду того, что синтаксис шаблонного класса проверяется там где инстанциируется, а не сразу по включению.

Автор: Burka 19.6.2012, 23:31
че то ничего у меня не получается, все равно ругается. вот такая структура.

Action.h
Код

#pragma once
#include "shared.h"
class Action
{
   void execute(Object*, Object*);
};


Object.h
Код

#pragma once
#include "shared.h"
class Object
{
   Action* current;
};



Place.h
Код

#pragma once
#include "shared.h"
class Place : public Object
{
   
};



Human.h
Код

#pragma once
#include "shared.h"
class Human: public Object
{
   
};


World.h
Код

#pragma once
#include "shared.h"
class World
{
   list<Object*> Objects;
   vector< vector< Place* > > WorldMatrix;
};




Shared.h
Код

#pragma once
#include "Action.h"
#include "Object.h"
#include "Place.h"
#include "Human.h"
#include "World.h"



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

Автор: Dem_max 20.6.2012, 06:12
в Shared.h сделай объявление
Код

#ifndef SHARED_H
#define SHARED_H

#include "Action.h"
#include "Object.h"
#include "Place.h"
#include "Human.h"
#include "World.h"

class Action;
class Object;
// ....... и т.д.

#endif


теперь как бы единица компиляции у которой подключен хеадер Shared.h будет видеть что мол объявлен такой то класс.
А уже на этапе линковки все это будет соединяться вместе. 

Автор: Burka 20.6.2012, 07:24
а #pragma once разве не тоже самое делает?

Автор: math64 20.6.2012, 08:18
#pragma once понимают не все компиляторы, а #ifndef - #define - #endif все.
Но лучше писать код так, чтобы ни #pragma once, ни #ifndef - #define - #endif были не обазательны, а были только доп. страховкой:
Код

// Action.h
class Object;
class Action
{
   void execute(Object*, Object*);
};
// Object.h - едиственный файл, где #pragma once или #ifndef - #define - #endif необходимы
#pragma once
#ifndef OBJECT_H
#define OBJECT_H
class Action;
class Object
{
   Action* current;
};
#endif
//Place.h
#include "Object.h"
class Place : public Object
{
   
};
//Human.h
#include "Object.h"
class Human: public Object
{
   
};
//World.h
#include <list>
#include <vector>
class Object;
class Place;
class World
{
   std::list<Object*> Objects;
   std::vector< std::vector< Place* > > WorldMatrix;
};
//Shared.h
#include "Action.h"
#include "Object.h"
#include "Place.h"
#include "Human.h"
#include "World.h"

+ добавь для страховки #pragma once и/или #ifndef - #define - #endif в остальных файлах, но всё будет работать без них

Автор: Burka 20.6.2012, 23:01
Спасибо больше, понял наконец то в чем дело)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)