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

Рекурсивный include, как грамотней сделать? - C++

Восстановить пароль Регистрация
 
ФараоН
Заблокирован
19.03.2014, 21:45     Рекурсивный include, как грамотней сделать? #1
Привет! Что - то я совсем онубел Есть два класса, вот их хэдэры:
C++
1
2
3
4
5
6
7
8
9
10
//Base.h
#pragma once
#include "Child.h"
class Base
{
public:
    Base(void);
    virtual ~Base(void);
    Child *child;
};
C++
1
2
3
4
5
6
7
8
9
10
//Child.h
#pragma once
#include "base.h"
 
class Child : public Base
{
public:
    Child(void);
    virtual ~Child(void);
};
В общем в базовом классе Base нужен указатель на дочерний класс Child. В Child понятное дело подключаю base.h (т.к. он от него наследуется), но поскольку в базовом классе нужен указатель на Child.h, подключаю в base.h файл child.h. Но тут получается как бы рекурсивный инклюд, тоесть бэйщ ссылается на чайла, а чайлд на бейза, если убрать #pragma once, будет fatal error C1014: too many include files : depth = 1024 (т.к. рекурсия), если не убирать, то соответственно error C2504: 'Base' : base class undefined, как лучше сделать для создания указателя на дочку в бэйзе?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
fishec
 Аватар для fishec
118 / 118 / 30
Регистрация: 07.09.2013
Сообщений: 337
19.03.2014, 21:50     Рекурсивный include, как грамотней сделать? #2
Можно использовать конструкцию #ifndef #define #endif
ФараоН
Заблокирован
19.03.2014, 21:53  [ТС]     Рекурсивный include, как грамотней сделать? #3
Цитата Сообщение от fishec Посмотреть сообщение
Можно использовать конструкцию #ifndef #define #endif
А смысл? Это то же самое, что и #pragma once
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
19.03.2014, 21:59     Рекурсивный include, как грамотней сделать? #4
Сообщение было отмечено автором темы, экспертом или модератором как ответ
В Base.h, вместо #include "Child.h", достаточно просто:
C++
1
class Child;
ФараоН
Заблокирован
19.03.2014, 22:01  [ТС]     Рекурсивный include, как грамотней сделать? #5
не, ну конечно можно создать общий файл с инклюдами и того и того или базовый класс над базовым, может интерфейсный даже, так же с инклюдами всего, но это как - то не по фэн шую .... Может есть у кого варианты?
DrOffset
6462 / 3836 / 887
Регистрация: 30.01.2014
Сообщений: 6,631
19.03.2014, 22:03     Рекурсивный include, как грамотней сделать? #6
ФараоН, слушай alsav22, он дело говорит.
zss
Модератор
Эксперт С++
 Аватар для zss
5956 / 5561 / 1788
Регистрация: 18.12.2011
Сообщений: 14,211
Завершенные тесты: 1
19.03.2014, 22:05     Рекурсивный include, как грамотней сделать? #7
Что-то Вы проблему создали на пустом месте.
1. Есть файл base.h - описание базового класса.
2. Есть файл child.h производного класса,
в него включаем строку
C++
1
#include "base.h"
Итак получается, если нам нужен только базовый класс,
то подключаем base.h, если производный (или оба),
то подключаес child.h
ФараоН
Заблокирован
19.03.2014, 22:15  [ТС]     Рекурсивный include, как грамотней сделать? #8
Цитата Сообщение от alsav22 Посмотреть сообщение
class Child;
Вот я олух, забыл! Спасибо!
Но, class Child надо использовать не в место, а в дополнение... Иначе при попытке создания этого классы вылетит - но апроритэйт дефаул конструктор, т.к. компилятор в бэйзе же понятия не имеет, что за чайлда ты как бы объявляешь ...
C++
1
2
3
4
5
6
7
8
9
10
#pragma once
#include "Child.h"
class Child;
class Base
{
public:
    Base(void);
    virtual ~Base(void);
    Child *child;
};
Добавлено через 1 минуту
Цитата Сообщение от zss Посмотреть сообщение
Итак получается, если нам нужен только базовый класс
тут как бы нужен указатель на производный класс в базовом классе ...
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
19.03.2014, 22:16     Рекурсивный include, как грамотней сделать? #9
Цитата Сообщение от ФараоН Посмотреть сообщение
Но, class Child надо использовать не в место, а в дополнение...
В .h не надо.
ФараоН
Заблокирован
19.03.2014, 22:20  [ТС]     Рекурсивный include, как грамотней сделать? #10
Цитата Сообщение от alsav22 Посмотреть сообщение
В .h не надо.
да, верно, я чушь написал, т.к. с H файлом в бейзе опять pragma once не даст два раза включиться как бы и будет тоже самое, НО, если писать просто в base.h строку class Child; как предлагалось выше, то получается как бы ерунда, тоесть компилятор вообще не знает в base.h, что за класс как бы ты объявляешь, откуда он может знать, что где - то есть файл, в котором объявлен Child...
По этому, в при попытке создать объект класса Child, например, в конструкторе класса Base:
C++
1
2
3
4
Base::Base(void)
{
    child = new Child;  
}
получаем 'Child' : no appropriate default constructor available
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
19.03.2014, 22:45     Рекурсивный include, как грамотней сделать? #11
Цитата Сообщение от ФараоН Посмотреть сообщение
например, в конструкторе класса Base:
В файле, где этот конструктор, какие инклуды сделаны?

???
C++
1
2
#include "Base.h"
#include "Child.h"
Добавлено через 5 минут
Цитата Сообщение от ФараоН Посмотреть сообщение
'Child' : no appropriate default constructor available
Реализация конструктора по умолчанию Child имеется?
ФараоН
Заблокирован
19.03.2014, 22:49  [ТС]     Рекурсивный include, как грамотней сделать? #12
Цитата Сообщение от alsav22 Посмотреть сообщение
В файле, где этот конструктор, какие инклуды сделаны?
C++
1
2
3
4
5
6
7
8
9
10
11
12
#include "stdafx.h"
#include "Base.h"
 
Base::Base(void)
{
    child = new Child;  
}
 
 
Base::~Base(void)
{
}
Да всё, я понял, так как я захотел - сделать нельзя, т.к. классы в разных файлах, вот что я понял:
1. Наверное не целесообразно в базовом классе делать указатели на дочерние классы, лучше уж делать указатели на самого себя, тоесть на Base, а где надо - приводить их к чему надо
2. Если уж так надо сделать, лучше все инклюды выносить вообще в отдельный файл и подключать везде только его и заодно сделать этот файл прекомпайл хэдэром ...

Добавлено через 3 минуты
Цитата Сообщение от alsav22 Посмотреть сообщение
Реализация консторуктора по умолчанию Child имеется?
ну вот как бы всё:
C++
1
2
3
4
5
6
7
8
9
10
//Base.h
#pragma once
class Child;
class Base
{
public:
    Base(void);
    virtual ~Base(void);
    Child *child;
};
C++
1
2
3
4
5
6
7
8
9
//Base.cpp
#include "Base.h"
Base::Base(void)
{
    child = new Child;   //error C2512: 'Child' : no appropriate default constructor available !!!
}
Base::~Base(void)
{
}
C++
1
2
3
4
5
6
7
8
9
10
//Child.h
#pragma once
#include "Base.h"
class Child : Base
{
public:
    Child(void);
    ~Child(void);
    int u;
};
C++
1
2
3
4
5
6
7
8
//Child.cpp
#include "Child.h"
Child::Child(void)
{
}
Child::~Child(void)
{
}
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
19.03.2014, 23:22     Рекурсивный include, как грамотней сделать? #13
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от alsav22 Посмотреть сообщение
#include "Base.h"
#include "Child.h"
C++
1
2
3
4
5
6
7
8
9
10
11
//Base.cpp
#include "Base.h"
#include "Child.h"
 
Base::Base(void)
{
    child = new Child;   //error C2512: 'Child' : no appropriate default constructor available !!!
}
Base::~Base(void)
{
}
ФараоН
Заблокирован
19.03.2014, 23:30  [ТС]     Рекурсивный include, как грамотней сделать? #14
да, что - то я в азах запутался, вот что значит самоучка
Всё верно, конечно же alsav22. Но всё равно я подумал, что лучше сделать общий прекомпайл и вообще наверное не красиво объявлять в базовом классе - дочерние...
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11848 / 6827 / 772
Регистрация: 27.09.2012
Сообщений: 16,930
Записей в блоге: 2
Завершенные тесты: 1
20.03.2014, 09:51     Рекурсивный include, как грамотней сделать? #15
Цитата Сообщение от ФараоН Посмотреть сообщение
Это то же самое, что и #pragma once
прагмы не стандартизированы, а значит компилятор может не поддерживать pragma once
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16846 / 5267 / 323
Регистрация: 30.03.2009
Сообщений: 14,173
Записей в блоге: 26
20.03.2014, 09:57     Рекурсивный include, как грамотней сделать? #16
Цитата Сообщение от ФараоН Посмотреть сообщение
В общем в базовом классе Base нужен указатель на дочерний класс Child
Это уже говорит о том, что классы спроектированы неправильно. Базовый класс вообще ничего не должен знать о своих потомках
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.03.2014, 11:21     Рекурсивный include, как грамотней сделать?
Еще ссылки по теме:

Как грамотней писать объявление указателя? C++
#include как и когда? C++
Как грамотней писать код? C++

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

Или воспользуйтесь поиском по форуму:
zss
Модератор
Эксперт С++
 Аватар для zss
5956 / 5561 / 1788
Регистрация: 18.12.2011
Сообщений: 14,211
Завершенные тесты: 1
20.03.2014, 11:21     Рекурсивный include, как грамотней сделать? #17
Цитата Сообщение от Evg Посмотреть сообщение
Базовый класс вообще ничего не должен знать о своих потомках
Прошу обратить особое внимание именно на это!!!!
Если предполагается использование методов производного класса,
то это надо делать исключительно через виртуальные функции.
Yandex
Объявления
20.03.2014, 11:21     Рекурсивный include, как грамотней сделать?
Ответ Создать тему
Опции темы

Текущее время: 16:59. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru