Объявление внутреннего класса
От: Liza  
Дата: 14.07.06 19:05
Оценка:
Доброго времени суток!

Возможно ли оъявить внутренний класс, не определяя при этом класс, который его содержит?

То есть, cуществуют вложенные друг в друга классы:
// foo.hpp

class Foo
{
  ...
    class Bar { ... }
    ...
}


Хочется сделать что-то типа того:

// test.hpp

// #include "foo.hpp" <- не вкючаем

// пытаемся объявить внутренний класс..
class Foo;
class Foo::Bar;

// ..чтобы была возможность объявить, например, следующие объекты
Foo::Bar *pDummy;
void test(Foo::Bar b);


Вопрос интересует меня, в основном, с академической точки зрения, поэтому не надо успокаивать меня, утверждая, что потребность в таком объявлении является следствием плохого дизайна
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: Объявление внутреннего класса
От: Анатолий Широков СССР  
Дата: 14.07.06 20:02
Оценка:
Нет, к сожалению, такого объявления сделать нельзя, если только foo не превратить в пространство имен.
Re[2]: Объявление внутреннего класса
От: Liza  
Дата: 17.07.06 14:06
Оценка:
Здравствуйте, Анатолий Широков, Вы писали:

АШ>Нет, к сожалению, такого объявления сделать нельзя, если только foo не превратить в пространство имен.


Спасибо.
В случае, если бы это было пространство имен, пришлось бы, как я понимаю, сделать так:

// test.hpp
// #include "foo.hpp" <- не вкючаем

namespace Foo
{
    class Bar;
}

Foo::Bar *pDummy;
...


Насколько это общепринятая практика? Я имею в виду:


namespace std
{
    template class string<...>;
    template class vector<...>;
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Объявление внутреннего класса
От: Анатолий Широков СССР  
Дата: 17.07.06 14:39
Оценка:
L>Насколько это общепринятая практика? Я имею в виду:

L>

L>namespace std
L>{
L>    template class string<...>;
L>    template class vector<...>;
L>}

L>


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


// mylib.h
namespace mylib
{
   class foo{};
}

// yourlib.h
namespace yourlib
{
   class foo{};
}

// main.cpp
#include "mylib.h"
#include "yourlib.h"

int main()
{
   mylib::foo f1;
   yourlib::foo f2;
   ...
}
Re[4]: Объявление внутреннего класса
От: Liza  
Дата: 17.07.06 15:15
Оценка:
L>>Насколько это общепринятая практика? Я имею в виду:

L>>

L>>namespace std
L>>{
L>>    template class string<...>;
L>>    template class vector<...>;
L>>}

L>>


АШ>Пространства имен были введены для решения проблемы конфликта имен. Поэтому это даже не общепринятая, а единственно возможная практика в условиях мультибиблиотечкой среды:


Это понятно. Насколько часто встречается в коде именно не включение "mylib.h" и "yourlib.h", а объявление функций и классов в них содержащихся? В заголовочных файлах. С целью ускорить компиляцию программы.

// main.h

// #include <vector>
// #include "yourlib.h"


namespace std
{
    template class vector<...>;
}

namespace yourlib
{
   class foo{};
}

void bar(std::vector<yourlib::foo> vf);


Если я правильно понимаю, то для стандартных контейнеров это сдеалть не так просто, потому что реальное количество параметров в них может зависеть от реализации STL (то есть, может быть vector<T, allocator<T>, NonDocumentedParametr = DefaultND>)...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: Объявление внутреннего класса
От: Анатолий Широков СССР  
Дата: 17.07.06 15:29
Оценка:
L>Это понятно. Насколько часто встречается в коде именно не включение "mylib.h" и "yourlib.h", а объявление функций и классов в них содержащихся? В заголовочных файлах. С целью ускорить компиляцию программы.

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

В качестве примера Вы можете посмотреть iosfwd из stl, который можно использовать в интерфейсной части класса использующего потовую библиотеку stl:


#include <iosfwd>

class foo
{
   friend std::ostream& operator<<(std::ostream &stream, foo const &o);
...
};
Re: Объявление внутреннего класса
От: Trapper  
Дата: 27.10.06 14:36
Оценка:
Здравствуйте, Liza, Вы писали:

L>Доброго времени суток!


L>Возможно ли объявить внутренний класс, не определяя при этом класс, который его содержит?


Вроде как у меня получилось: для этого внешний класс должен быть шаблонным. Тогда компилятор не будет пытаться с ним что-нибудь делать, пока не увидит его инстанцирования. Вот пример:


template <typename Dummy>
class Foo;

template <typename Dummy>
void f (typename Foo<Dummy>::Bar & b);


При компиляции VS 2003 этот код проходи на ура. У кого есть предложения или замечания?
Trapper
Re[2]: Объявление внутреннего класса
От: rg45 СССР  
Дата: 27.10.06 15:28
Оценка:
"Trapper" <3294@users.rsdn.ru> wrote in message news:2186820@news.rsdn.ru...
>
>
> template <typename Dummy>
> class Foo;
> 
> template <typename Dummy>
> void f (typename Foo<Dummy>::Bar & b);
>

>
> При компиляции VS 2003 этот код проходи на ура. У кого есть предложения или замечания?

Единственное замечание: при вызове такой шаблонной функции копилятор не сможет вывести параметр шаблона, его прийдется указывать всегда явно. А в остальном все вполне законно.
Posted via RSDN NNTP Server 2.0
--
Справедливость выше закона. А человечность выше справедливости.
Re[3]: Объявление внутреннего класса
От: Trapper  
Дата: 27.10.06 15:40
Оценка:
R>Единственное замечание: при вызове такой шаблонной функции копилятор не сможет вывести параметр шаблона, его прийдется указывать всегда явно. А в остальном все вполне законно.

Да, это проблема. Кроме того приходится делать класс шаблонным и связываться со всеми проблемами, которые из этого следуют. Но работает
Trapper
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.