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


Автор: Ptica 1.6.2005, 12:25
Научите глупую птицу...
Я хочу, чтобы у меня в структуре класса А был указатель на объект класса В, и одновременно, чтобы в структуре класса В был указатель на объект класса А. Например, есть класс А - некий элементарный объект. Есть класс Б - контейнер для класса А. И теперь я хочу, чтобы каждый объект А содержал бы в себе ссылку на "родительский" контейнер.
Во 2-х Турбо Сях я написал:
Код


 struct B
 {
   struct A *first,*last;
   int n;
 };

 struct A
 {
   int i, j;
   struct B *parent;
 };


и вроде бы ничего. Как провернуть то же самое с классами?
smile smile

Автор: ManiaK 1.6.2005, 12:33
Разницы между классами и структурами в Си++ нет. Разве что вот такое сделать:
Код

class B;
class A;

class B    
 {    
public:
   A *first,*last;    
   int n;    
 };    
 class A    
 { 
public:   
   int i, j;    
   B *parent;    
 };

Автор: Ptica 1.6.2005, 12:48
Спасибо! Вот до этого
Код

class B;
class A;

я не додумался. smile

Автор: Kolia 5.6.2005, 18:12
А если это не структура, а класс, в методах которого используются эти самые указатели, которые сами вызывают свои методы? Тогда такая фишка не проходит. Компилятор пишет, что методы не определене. Сам класс объявлен. Но его методы нет.

Хотя у меня щас родилась мысль также объявить и методы. Пойду попробую. Только как-то дешево выглядеть будет, если пройдет.

Не прошло smile

Автор: Mayk 5.6.2005, 22:14
Если я правильно понял вопрос, то можно так:
вначале объявляем эти методы в обоих классах как обычно
потом имплементируем их как inline.



Ну например так(возьмем два класса чисел: int, float, и будем конвертировать их меж собой):

TypeFloat.h
Код

#ifndef __tfloat_h
#define __tfloat_h 1
class TypeInt;
class TypeFloat
{
    float m_fvalue;
    public:
    TypeFloat(int i);
    TypeInt makeInt() const;
};
#include "typeint.h"
#include "conversion.h"
#endif


TypeInt.h
Код

#ifndef __tint_h
#define __tint_h 1
class TypeFloat;
class TypeInt;
{
    int m_ivalue;
    public:
    TypeInt(float f);
    TypeFloat makeFloat() const;
};
#include "typefloat.h"
#include "conversion.h"
#endif


conversion.h
Код

#ifndef __conv_h
#    if  __tint_h && __tfloat_h
#        define __conv_h
inline TFloat TInt::makeFloat() const
{
    return TFloat(m_ivalue);
}

inline TInt TFloat::makeInt() const
{
    return TInt(m_fvalue);
}
#    endif
#endif


А теперь разберемся как оно работает
1) Подключаем typefloat.h
1.1)Препроцессор определяет __tfloat_h, компилятор обрабатывает класс TypeFloat,
1.2)Препроцессор переходит в TypeInt.h, определяет __tint_h, компилятор обрабатывает класс TypeInt
1.3) Препроцессор идет в typefloat.h, но не обрабатывает его, так кае __tfloat_h уже определен
1.4) Препроцессор идет в conversion.h, так как __conv_h не определен, а __tfloat_h и __tint_h определены, то компилятор успешно обрабатывает методы, препроцессор определяет __conv_h
1.5) conversion.h заканчивается без ошибок
1.6) typeint.h заканчивается без ошибок
1.7) препроцессор входит в conversion.h из typefloat.h, но получает пинок, так как __conv_h уже определен.
1.8) typefloat.h заканчивается без ошибок
2) Если первым подключить typeint.h, то результат аналогичен.
3) Если подключить conversion.h, то он ничего не определит, так как __tfloat_h и __tint_h еще не определены.

В принципе из typefloat.h можно убрать #include "typeint.h" и из typeint.h можно убрать #include "typefloat.h". Тогда где-то в основной программе потребуется два инклюда: один на typefloat.h, другой на typeint.h.




Автор: ManiaK 7.6.2005, 15:04
Цитата(Kolia @ 5.6.2005, 18:12)
А если это не структура, а класс, в методах которого используются эти самые указатели, которые сами вызывают свои методы?


Стуктура от класса в Си++ отличается только областью доступа по умолчанию; в struct - public, class - protected (если память не изменяет).

Код

struct A;
struct B;

struct A {
B* pB;
void Func();
};

struct B {
A* pA;
void Func();
};

void A::Func() { pB->Func(); }
void B::Func() { pA->Func(); }


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

Код

struct B;

void Func() {
B* pB;
pB = NULL;// Нормально
}

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