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


Автор: Mongol 10.12.2009, 11:20
Учебное задание. Нужно реализовать программу по http://en.wikipedia.org/wiki/Double_dispatch.
Затруднения в том что при описании классов Starship нужно что бы были описаны классы Asteroid, и наоборот что бы описать Asteroid нужно что были описаны предварительно классы  Starship. (подскажите как это по нормальному называется). Пробовал сначала только делать объявления(class AsteroidLevel1;), разбросать все по разным файлам в надежде на компоновщика, - ничего не помогает:

Код

#include <iostream>

class StarshipLevel1
{
    public:
    void func() { std::cout << "starshipLevel1" << std::endl; }
    virtual void collideWith(AsteroidLevel1* asteroid) { asteroid->collideWith(this); }
};

class StarshipLevel2 : public StarshipLevel1
{
    public:
    void func() { std::cout << "starshipLevel2" << std::endl; }
    virtual void collideWith(AsteroidLevel1* asteroid) { asteroid->collideWith(this); }
};

class AsteroidLevel1
{
    public:
    virtual void collideWith(StarshipLevel1* theStarship) { std::cout << "AsteroidLevel1 collide with -- "; theStarship->func(); }
    virtual void collideWith(StarshipLevel2* theStarship) { std::cout << "AsteroidLevel1 collide with -- "; theStarship->func(); }
};

class AsteroidLevel2 : public AsteroidLevel1
{
    public:
    virtual void collideWith(StarshipLevel1* theStarship) { std::cout << "AsteroidLevel2 collide with -- "; theStarship->func(); }
    virtual void collideWith(StarshipLevel2* theStarship) { std::cout << "AsteroidLevel2 collide with -- "; theStarship->func(); }
};

int main(int argc, char** argv)
{
    StarshipLevel1 theStarshipLevel1;
    StarshipLevel2 theStarshipLevel2;
    
    AsteroidLevel1 theAsteroidLevel1;
    //without using any dynamic dispatch
//     theAsteroidLevel1.collideWith(&theStarshipLevel1);
//     theAsteroidLevel1.collideWith(&theStarshipLevel2);
    
    AsteroidLevel2 theAsteroidLevel2;
    //without using any dynamic dispatch
//     theAsteroidLevel2.collideWith(&theStarshipLevel1);
//     theAsteroidLevel2.collideWith(&theStarshipLevel2);
    
    AsteroidLevel1* pAsteroidLevel1 = &theAsteroidLevel1;
    //using dynamic dispatch
//     pAsteroidLevel1->collideWith(&theStarshipLevel1);
//     pAsteroidLevel1->collideWith(&theStarshipLevel2);
    
    pAsteroidLevel1 = &theAsteroidLevel2;
    //using dynamic dispatch
//     pAsteroidLevel1->collideWith(&theStarshipLevel1);
//     pAsteroidLevel1->collideWith(&theStarshipLevel2);
    
    StarshipLevel1* pStarshipLevel1 = &theStarshipLevel2;
    std::cout << "\n";
//     theAsteroidLevel1.collideWith(&theStarshipLevel1);
//     theAsteroidLevel1.collideWith(pStarshipLevel1);
    std::cout << "\n";
//     theAsteroidLevel2.collideWith(&theStarshipLevel1);
//     theAsteroidLevel2.collideWith(pStarshipLevel1);
    
    //pAsteroidLevel1->collideWith(&theStarshipLevel1);
    //pAsteroidLevel1->collideWith(pStarshipLevel1);
    
    //Double dispatch
    pStarshipLevel1->collideWith(theAsteroidLevel1);
    pStarshipLevel1->collideWith(theAsteroidLevel2);
    pStarshipLevel1->collideWith(pAsteroidLevel1);
}

Автор: djamshud 10.12.2009, 11:37
Forward declaration называется, емнип.

Код

class B;

class A{
B *object;
A();
};

class B{
A *object;
B();
};

A::A(){
this->object=new B;
}

B::B(){
this->object=new A;
}



Можно разносить по разным файлам.

Суть в том, что объект нельзя использовать, пока его класс не описан. Но с другой стороны его можно "упоминать" в ряде случаев. Например через указатель (как в примере), в качестве параметра или возвращаемого значения функции.

В примере сначала описаны классы, а только потом реализованы их конструкторы, когда уже ничто не мешает полностью использовать объекты соседнего класса.

Автор: Mongol 10.12.2009, 12:37
Спасибо. Проблема решена.

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