Specjalizacja funkcji składowej szablonu klas
Ostatnio zmodyfikowano 2014-04-02 20:03
Mig Temat założony przez niniejszego użytkownika |
Specjalizacja funkcji składowej szablonu klas » 2014-04-01 20:41:26 Witam mam problem mianowicie posiadam klasę z takim oto interfejsem namespace gg { class Command; template < typename Type > class GAMEGUIDLL_API SharedPtrCommand sealed { public: SharedPtrCommand(); ~SharedPtrCommand() = default; SharedPtrCommand( SharedPtrCommand < Type > && spc ); SharedPtrCommand( const SharedPtrCommand < Type > & spc ); template < typename OtherType > SharedPtrCommand( SharedPtrCommand < OtherType > && spc ); template < typename OtherType > SharedPtrCommand( const SharedPtrCommand < OtherType > & spc ); SharedPtrCommand < Type >& operator =( SharedPtrCommand < Type > && spc ); SharedPtrCommand < Type >& operator =( const SharedPtrCommand < Type > & spc ); template < typename OtherType > SharedPtrCommand < Type >& operator =( SharedPtrCommand < OtherType > && spc ); template < typename OtherType > SharedPtrCommand < Type >& operator =( const SharedPtrCommand < OtherType > & spc ); bool operator !() const; bool friend operator ==( const SharedPtrCommand < Type > & spc1, const SharedPtrCommand < Type > & spc2 ); template < typename AType, typename BType > bool friend operator ==( const SharedPtrCommand < AType > & spc1, const SharedPtrCommand < BType > & spc2 ); bool friend operator !=( const SharedPtrCommand < Type > & spc1, const SharedPtrCommand < Type > & spc2 ); template < typename AType, typename BType > bool friend operator !=( const SharedPtrCommand < AType > & spc1, const SharedPtrCommand < BType > & spc2 ); Type & operator *() const; Type * operator ->() const; Type * Get() const; SharedPtrCommand < Type > Clone() const; private: std::shared_ptr < Type > _command; }; }
definicje wszystkich funkcji składowych i zaprzyjaźnionych znajdują się poniżej definicji , problem w tym że posiadam również 3 klasy .Klasa Command to klasa abstrakcyjna , natomiast klasy SimpleCommand,oraz MacroCommand to jej podklasy konkretne problem w tym że chce by konstruktor klasy SharedPtrCommand dla każdego argumentu szablonu z wyjątkiem SharedPtrCommand<Command> tworzył obiekt przechowywanej klasy , mniej więcej o coś takiego mi chodzi : template < typename Type > gg::SharedPtrCommand < Type >::SharedPtrCommand() { _command = std::shared_ptr < Type >( new Type ); }
Problem w tym że klasa Command jest abstrakcyjna i nie mogę utworzyć jej więc chciałem wykorzystać do tego specjalizacje szablonu robiąc coś takiego : template <> gg::SharedPtrCommand < gg::Command >::SharedPtrCommand() { _command = std::shared_ptr < Command >( nullptr ); }
niestety umieszczenie tej specjalizacji w plikuCommand.cpp nic nie zmienia i dostaje taki log : :\users\adam\documents\visual studio 2013\projects\gamegui\gamegui\sharedptrcommand.h(57): error C2259: 'gg::Command' : cannot instantiate abstract class 2> due to following members: 2> 'void gg::Command::Execute(void) const' : is abstract 2> c:\users\adam\documents\visual studio 2013\projects\gamegui\gamegui\command.h(16) : see declaration of 'gg::Command::Execute' 2> c:\users\adam\documents\visual studio 2013\projects\gamegui\gamegui\sharedptrcommand.h(56) : while compiling class template member function 'gg::SharedPtrCommand<gg::Command>::SharedPtrCommand(void)' 2> c:\users\adam\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1.cpp(20) : see reference to function template instantiation 'gg::SharedPtrCommand<gg::Command>::SharedPtrCommand(void)' being compiled 2> c:\users\adam\documents\visual studio 2013\projects\consoleapplication1\consoleapplication1.cpp(20) : see reference to class template instantiation 'gg::SharedPtrCommand<gg::Command>' being compiled ========== Build: 1 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
jak mogę poradzić sobie z tym problemem ? |
|
Monika90 |
» 2014-04-02 07:12:51 Jawna specjalizacja musi być widoczna w każdej jednostce translacji, w której jest użyta i musi się w niej pojawić zanim zostanie użyta. Więc przenieś specjalizację do pliku nagłówkowego.
Zamiast jawnej specjalizacji można użyć std::is_abstract<T> z <type_traits>, by zadecydować czy tworzyć obiekt, czy nie.
|
|
Mig Temat założony przez niniejszego użytkownika |
» 2014-04-02 11:41:08 Dzięki wielkie ! |
|
Mig Temat założony przez niniejszego użytkownika |
» 2014-04-02 19:51:09 No niestety to nie koniec problemów , niestety is_abstract nie działa w taki sposób w jaki chciałem to wykorzystać , w samym ciele konstruktora jak zastosuję to jako warunek kompilator wywala błąd próby tworzenia instancji abstrakcyjnej klasy,natomiast gdy chce utworzyć specjalizacje w pliku nagłówkowym zawierającym np. klase abstrakcyjną Command otrzymuję komunikat następujący -> fatal error LNK1169: one or more multiply defined symbols found. |
|
Mig Temat założony przez niniejszego użytkownika |
» 2014-04-02 20:03:07 Informuję że sprawa jest nieaktualna wystarczyło umieścić podstawową wersje definicji konstruktora w klasie zamiast poza nią.Jeszcze raz dziękuje za odpowiedź. |
|
« 1 » |