Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Specjalizacja funkcji składowej szablonu klas

Ostatnio zmodyfikowano 2014-04-02 20:03
Autor Wiadomość
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

C/C++
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;
       
    }; // template class SharedPtrCommand
   
} // namespace gg



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 :

C/C++
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 :

C/C++
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 ?
P-107586
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.

P-107605
Mig
Temat założony przez niniejszego użytkownika
» 2014-04-02 11:41:08
Dzięki wielkie !
P-107608
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.
P-107629
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ź.
P-107630
« 1 »
  Strona 1 z 1