2009-08-10 12 views
12

Chcę użyć deklaracji forward klasy w moim oprogramowaniu, dzięki czemu mogę napisać na maszynie
i użyć ich w deklaracji pełnej klasy.C++ Deklaracje błędów klasy C++?

czymś tak:

class myclass; 
typedef boost::shared_ptr<myclass> pmyclass; 
typedef std::list<pmyclass > myclasslist; 

class myclass : public baseclass 
{ 
private:  // private member declarations 
     __fastcall myclass(); 

public:   // public member declarations 
     __fastcall myclass(myclass *Parent) 
      : mEntry(new myclass2()) 
      { 
      this->mParent = Parent; 
      } 
     const myclass *mParent; 
     myclasslist mChildren; 
     boost::scoped_ptr<myclass2> mEntry; 
}; 

więc moje pytanie brzmi: czy są jakieś wady tej metody? Przypominam sobie pewną dyskusję na temat problemów destruktora z deklaracją, ale nie wydostałem wszystkiego.
lub czy jest jakaś inna opcja do zaimplementowania czegoś takiego?

Dzięki.

EDIT: znalazłem dyskusję miałem na myśli: here

Odpowiedz

5

Od standardu C++:

5.3.5/5:

„Jeśli obiekt ma być usunięty niekompletne typu klasa w momencie usuwania , a cała klasa ma nietrywialny destruktor lub funkcję dealokacji , zachowanie jest niezdefiniowane. "

+0

cóż, przepraszam za głupotę, ale przeczytałem ją wcześniej i moje pytanie tutaj brzmi: jeśli jest zdefiniowane tuż po deklaracji, nie powinno być problemu, prawda? – Andrew

+1

Tak, dobrze, tak to czytam. Miejmy nadzieję, że nasze kompilatory będą zgodne ze standardami :-) –

22

Główną wadą jest wszystko. Deklaracje forward są kompromisem, aby zaoszczędzić czas kompilacji i pozwolić na cykliczne zależności między obiektami. Koszt jest jednak taki, że możesz użyć tego typu jako referencji i nie możesz nic zrobić z tymi odniesieniami. Oznacza to, że nie ma dziedziczenia, nie przekazujemy go jako wartości, nie używamy żadnego typu zagnieżdżonego lub typedef w tej klasie, itd ... To są wielkie wady.

Specyficzny problem z niszczeniem, o którym mówisz, polega na tym, że tylko forwardujesz deklarację typu i zdarza się, że usuwasz go tylko w module, zachowanie jest niezdefiniowane i nie zostanie zgłoszony żaden błąd.

Na przykład:

class A; 

struct C 
{ 
    F(A* a) 
    { 
     delete a; // OUCH! 
    } 
} 

Microsoft C++ 2008 nie będzie wywoływać żadnych destruktor i rzucać następujące ostrzeżenie:

warning C4150: deletion of pointer to incomplete type 'A'; no destructor called 
      : see declaration of 'A' 

więc trzeba zachować czujność, co nie powinno być problemem, jeśli traktujesz ostrzeżenia jako błędy.

+5

Jeśli cały ten ból zaoszczędził 30 minut czasu kompilacji w miesiącu, ale kosztuje godzinę czasu z zadeklarowanym bólem głowy - to tracisz ... Kup CPU z większą liczbą rdzeni i umożliwia raczej równoległą kompilację. Przynajmniej możesz zagrać na nim Skyrim z lepszą framerate. – Eloff