Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Порядок хедеров 
:(
    Опции темы
TGrey
Дата 28.11.2010, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: нет
Всего: 1



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

Class1
{
   Class2 *cs2;
   Class3 *cs3;
};
 
Class2
{
 
};
 
Class3:public Class2;
{
    Class(Class1 *c){ cs1 = c; }
    Class1 *cs1;
};

В основ ошибка была в конструктора класса 3, пишет, что объект не определен. Попробовал подключить Хедер с этим классом, и началось... ошибка на ошибке, то множественное определение, то еще что.
Как корректно это все подключить надо?

По совету прописал в каждом хедере
Цитата

TGrey[WoLf], Прописать в каждом хедере страж включения например
#ifndef _FILENAME_H_
#define _FILENAME_H_

И в конце файла #endif


Все равно жалуется
В таком случае жалуется на член-класса
Цитата

Class1 *cs1;
Type name expected, Declaration missing ;


Что с ним делать?
PM MAIL   Вверх
mes
Дата 28.11.2010, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



гугль : forward declaration


--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 28.11.2010, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



TGrey

Используй foward declaration.
допустим это файл class1.h
Код

class Class2;
class Class3;
Class1
{
   Class2 *cs2;
   Class3 *cs3;
};

и включаешь class2.h и class3.h в файле class1.cpp

Добавлено через 36 секунд
опоздал smile 
PM   Вверх
TGrey
Дата 28.11.2010, 18:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: нет
Всего: 1



Так у меня нет пока цппшников) Только хедеры, а функции определены внутри класса.
Вот у меня такой код
Код

#ifndef _CLASS3_H
        #define _CLASS3_H

class Class1;
class Class3 : public Class2
{
        Class1 *pl;
        ....
        void F()
        {
             pl->Get();
        }
};
#endif


Выдает мне ошибку что функция Гет не является членом Class1 потому, что тип еще не определен.

Или я так понимаю обязательно надо выносить реализацию в ЦППшники?

Это сообщение отредактировал(а) TGrey - 28.11.2010, 18:10
PM MAIL   Вверх
azesmcar
Дата 28.11.2010, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(TGrey @  28.11.2010,  18:05 Найти цитируемый пост)
Или я так понимаю обязательно надо выносить реализацию в ЦППшники?

нет, главное, чтобы там, где используешь все было включено.
PM   Вверх
TGrey
Дата 28.11.2010, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: нет
Всего: 1



Ну так а в чем же тогда дело? Код такой как я написал, все включено, почему оно рассказывает, что нет такой функции и тип не объявлен?
Можно же вызывать методы этого класса который перед основным написан?
PM MAIL   Вверх
mes
Дата 28.11.2010, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



хидеры не могут включать друг друга циклически  и поэтому один из классов получается не определенным на момент использования.. 

чтоб понять раскройте в один файл все инклуды и увидете что получится.. 
  либо повторное определение, если нет стражей
  иначе отсутствие определения..

эта тема обсуждалась не одну сотню раз, поэтому прежде всего:
Цитата(mes @  28.11.2010,  16:09 Найти цитируемый пост)
гугль : forward declaration 




--------------------
PM MAIL WWW   Вверх
TGrey
Дата 28.11.2010, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: нет
Всего: 1



Гуглил у них как-то все просто получается, а я как не пишу, постоянно новая ошибка.
Прикрепил архив с проектом. Посмотрите пожалуйста, что нужно, чтобы они заработали.
В Unit4.cpp подключены 3 хедера. Но между собой оно конфликтуют.

Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  qwe.rar 654,59 Kb
PM MAIL   Вверх
mes
Дата 28.11.2010, 20:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



приведите к этой схеме :
http://www.adp-gmbh.ch/cpp/forward_decl.html

Цитата(TGrey @  28.11.2010,  17:05 Найти цитируемый пост)
Или я так понимаю обязательно надо выносить реализацию в ЦППшники?

да, если иначе хидеры получаются циклически зависимыми..


Цитата(TGrey @  28.11.2010,  17:05 Найти цитируемый пост)
Вот у меня такой код

Код

class Class1;
...
        Class1 *pl;
        ....
    
             pl->Get();

объявления класса не достаточно для использования его содержимого, так как оно еще не определено..

Добавлено через 1 минуту и 32 секунды
вот еще куча тем 
http://forum.vingrad.ru/act-Search/CODE/sh...ward/index.html

Добавлено через 2 минуты и 38 секунд
и в первой же есть ответы на все ваши вопросы :
http://forum.vingrad.ru/forum/topic-144392...forward/15.html



--------------------
PM MAIL WWW   Вверх
TGrey
Дата 28.11.2010, 20:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: нет
Всего: 1



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

class CMap;
class Player;
class Enemy : public Player
{


Пишет что Player, должен быть заранее объявленным классом или структурой, и ругает все обращения к полям этого класса, говорит, что он еще не определен.
Я вообще не понимаю, что оно хочет.
Пожалуйста могли бы вы на моем примере вложенного проекта указать, как необходимо сделать, а я сяду разберу его.
PM MAIL   Вверх
mes
Дата 28.11.2010, 20:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(TGrey @  28.11.2010,  19:41 Найти цитируемый пост)
Пишет что Player, должен быть заранее объявленным классом или структурой, и ругает все обращения к полям этого класса, говорит, что он еще не определен.


Цитата(mes @  28.11.2010,  19:00 Найти цитируемый пост)
объявления класса не достаточно для использования его содержимого,


Добавлено через 1 минуту и 26 секунд
и перечитайте внимательней хотя бы : 


--------------------
PM MAIL WWW   Вверх
TGrey
Дата 28.11.2010, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: нет
Всего: 1



Ну я уже не знаю, я никак не пойму, что ему еще надо. Прочитал, ничего нового не увидел. smile 

Хорошо это действительно забавно, потому что я создал проект в Визуале, создал туже иерархию классов, подключил все, как и в Билдере, но разница лишь в том, что в Студии это все работает. smile 
Как это можно объяснить?

Это сообщение отредактировал(а) TGrey - 28.11.2010, 21:25
PM MAIL   Вверх
mes
Дата 28.11.2010, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



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


Цитата(TGrey @  28.11.2010,  19:41 Найти цитируемый пост)
Пишет что Player, должен быть заранее объявленным классом или структурой,

заранее определенным.. 



--------------------
PM MAIL WWW   Вверх
TGrey
Дата 28.11.2010, 21:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: нет
Всего: 1



Хорошо это действительно забавно, потому что я создал проект в Визуале, создал туже иерархию классов, подключил все, как и в Билдере, но разница лишь в том, что в Студии это все работает.  
Как это можно объяснить?
PM MAIL   Вверх
mes
Дата 28.11.2010, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(TGrey @  28.11.2010,  20:33 Найти цитируемый пост)
Хорошо это действительно забавно, потому что я создал проект в Визуале, создал туже иерархию классов, подключил все, как и в Билдере, но разница лишь в том, что в Студии это все работает.  
Как это можно объяснить? 

кривыми руками smile 


--------------------
PM MAIL WWW   Вверх
TGrey
Дата 28.11.2010, 21:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: нет
Всего: 1



Это само собой, были бы они ровные уже давно бы работало. Но почему та же структура файлов работает в студии, но не работает в Билдере. Отличие только в именах классов.
Код

//main.cpp
#include "cA.h"
#include "cB.h"
#include "cC.h"

int main()
{
    A *a;
    a = new A();
    a->b = new B(2);
    a->b->a = 3;
    return 0;
}
//------------------------------------------------------
//cA.h
#ifndef _CA_H
        #define _CA_H
class B;
class C;
class A
{
public:
    void D();
    B *b;
    C *c;
};
#endif
//-------------------------------------------------------------
//cB.h
#ifndef _CB_H
        #define _CB_H
class B
{
public:
    B(int a){};
    int a;
};
#endif
//---------------------------------------------------------------
//cC.h
#ifndef _CC_H
        #define _CC_H
class C : public B
{
public:
    C() : B(1){};
    int b;
};
#endif
//-----------------------------------------------------------------
//func.cpp
#include "cA.h"
#include "cB.h"
#include "cC.h"

void A::D()
    {
        b = new B(2);   //
        b->a = 3;
    }


Все тоже самое ведь?
PM MAIL   Вверх
mes
Дата 28.11.2010, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(TGrey @  28.11.2010,  20:54 Найти цитируемый пост)
Но почему та же структура файлов работает в студии, но не работает в Билдере. 

значит не все повторили..
Цитата(TGrey @  28.11.2010,  20:54 Найти цитируемый пост)
Все тоже самое ведь? 

нет.. в прошлых примерах был вызов (в хидере) метода одного класса другим..





--------------------
PM MAIL WWW   Вверх
TGrey
Дата 28.11.2010, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 1.12.2007

Репутация: нет
Всего: 1



Я после того изменил же, как и в Студии.
Код

//map.h
#ifndef _MAP_H
        #define _MAP_H
class Player;
class Enemy;
class CMap
{
public:
    CMap();

        int GetPlayerX();
        int GetPlayerY();

    void GetMap();
        //void DrawMap(TCanvas *Canvas);
    Player *pl;
    Enemy *en[4];
        /*Graphics::TBitmap *wall;
        Graphics::TBitmap *player;
        Graphics::TBitmap *empty;
        Graphics::TBitmap *enemy;
        Graphics::TBitmap *coin;*/
    char Map[25][25];
};
#endif

//player.h
#ifndef _MAP_H
        #define _MAP_H

enum Direction{ DLeft=0, DRight, DTop, DDown, DNone};

class Player
{
public:
    Player(int _x, int _y);
        void CanGo(char Map[25][25], Direction d);
    bool CanGo(char Map[25][25], int nx, int ny);
        virtual void DoMove( char Map[25][25] );
        bool Free(Direction d, char Map[25][25]);
        virtual bool NewOffset(char Map[25][25]);

//private:
        int points;
//protected:
        Direction dir;
        Direction gooddir;
        Direction nextdir;
    int x;
    int y;
        int offsetx;
        int offsety;
};

#endif


//enemy.h
#ifndef _ENEMY_H
        #define _ENEMY_H
//class CMap;
//class Player;
class Enemy //: public Player
{
        //CMap *pl;
public:
    //Enemy(int _x, int _y/*, CMap *p*/): Player(_x, _y);

        //virtual void DoMove( char Map[25][25] );
        //virtual bool NewOffset(char Map[25][25]);
};

#endif

//func.cpp
#include "Map.h"
#include "Player.h"
#include "Enemy.h"
#include <fstream.h>


    CMap::CMap()
        {
                //pl = new Player(1,1);
                //en[0] = new Enemy(1,1);
                //en[1] = new Enemy(1,2);
                //en[2] = new Enemy(1,2);
                //en[3] = new Enemy(1,2);

                /*wall = new Graphics::TBitmap();
                player = new Graphics::TBitmap();
                empty = new Graphics::TBitmap();
                enemy = new Graphics::TBitmap();
                coin = new Graphics::TBitmap();

                wall->LoadFromFile("wall.bmp");
                player->LoadFromFile("man.bmp");
                empty->LoadFromFile("empty.bmp");
                enemy->LoadFromFile("enemy.bmp");
                coin->LoadFromFile("coin.bmp"); */
        }

        int CMap::GetPlayerX()
        {
                return pl->x;
        }

        int CMap::GetPlayerY()
        {
                return pl->y;
        }
....


Ну и вот стразу уже тут ругается на конструктор
Цитата

//pl = new Player(1,1);

и на
Цитата

        int CMap::GetPlayerX()
        {
                return pl->x;
        }

типа Х не является полем потому что Плеер еще не определен.

Добавлено через 9 минут
Все загадка разгадана((( Виной всему кривые руки... Я копи\пастил защиту от повторного включения хедеров и в файле Плеер.ш осталась проверка на инклуд Карты. Потому оно Плеер.ш просто не включало никогда.
Теперь все работает. smile 
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0621 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.