Fehler beim Zugrif auf geerbte statische Funtion



  • Folgende Fehlermeldung bringt mich nicht weiter:

    ./util/ASingleton.hpp:24: error: ‘static T* util::ASingleton<T>::GetSingleton() [with T = net::CServer]’ is inaccessible
    main.cpp:22: error: within this context
    

    Was mache ich falsch?

    ASingleton.hpp

    /*------------------------------------Makros und Includes---------------------------------------*/
    #ifndef SINGLETON_H
    #define SINGLETON_H
    
    /*----------------------------------------------------------------------------------------------*/
    
    namespace util
    {
    
        /** 
          * \brief Der Singleton stellt sicher, dass eine Klasse nur ein mal existiert.
          *
          * ASingleton ist eine Abstrakte Basisklasse, von der sämmtliche Unterklassen erben, die nur einmal
          * existieren Dürfen.
          */
        template <typename T>
        class ASingleton
        {
        public:
            ///rein virtueller Destruktor verhindert Instantiirung. Die Klasse ist nur zum Ableiten gedacht
            virtual ~ASingleton()=0;
    
            ///Diese Funktion gibt einen Pointer auf das Singleton zurück
            static T* GetSingleton()
            {
                if(m_Singleton == NULL)
                {
                    m_Singleton = new T;
                }
    
                return m_Singleton;
            }
    
        protected:
            /// Instanz-Pointer
            static T* m_Singleton;
        };
    
        template <typename T> ASingleton<T>::~ASingleton()
        {
    
        }
    
        template <typename T> T* ASingleton <T>::m_Singleton = NULL;
    
    }
    
    #endif
    

    CServer.hpp

    /*------------------------------------Makros und Includes---------------------------------------*/
    #ifndef CSERVER_HPP_INCLUDED
    #define CSERVER_HPP_INCLUDED
    
    //Library-Includes
    
    //Projekt-Includes
    #include "util/ASingleton.hpp"
    
    /*----------------------------------------------------------------------------------------------*/
    
    namespace net
    {
        /** \brief Die Klasse CServer ist das Zentrale Modul des Serverseitigen Netzwerks
          * 
          */
        class CServer
                : public ANetwork,
                         util::ASingleton<CServer>
        {
            // [...]
        };
    }
    
    #endif // CSERVER_HPP_INCLUDED
    

    main.cpp

    #include <iostream>
    
    #include "net/server/CServer.hpp"
    
    int main()
    {
        net::CServer * server = net::CServer::GetSingleton();
    }
    


  • Hmm wie ist der Konstruktor von CServer definiert? Also welchen Access-Bereich?



  • CServer.cpp

    CServer::CServer()
            : log_("CServer", log::CLog::NOTICE)
        {
            peer_ = RakNetworkFactory::GetRakPeerInterface();
        }
    


  • Davon abgesehen, dass peer_ wahrscheinlich auch in die Initialisierungsliste kann, wollte ich nur wissen ob es public, private oder protected ist ...
    wobei das ist eigtl. unwichtig ... seh ich gerade erst.

    #ifndef SINGLETON_H
    #define SINGLETON_H
    
    /*----------------------------------------------------------------------------------------------*/
    
    namespace util
    {
    
        /**
          * \brief Der Singleton stellt sicher, dass eine Klasse nur ein mal existiert.
          *
          * ASingleton ist eine Abstrakte Basisklasse, von der sämmtliche Unterklassen erben, die nur einmal
          * existieren Dürfen.
          */
        template <typename T>
        class ASingleton
        {
        public:
            ///rein virtueller Destruktor verhindert Instantiirung. Die Klasse ist nur zum Ableiten gedacht
            virtual ~ASingleton()=0;
    
            ///Diese Funktion gibt einen Pointer auf das Singleton zurück
            static T* GetSingleton()
            {
                if(m_Singleton == NULL)
                {
                    m_Singleton = new T;
                }
    
                return m_Singleton;
            }
    
        protected:
            /// Instanz-Pointer
            static T* m_Singleton;
        };
    
        template <typename T> ASingleton<T>::~ASingleton()
        {
    
        }
    
        template <typename T> T* ASingleton <T>::m_Singleton = NULL;
    
    }
    
    #endif
    

    hmm 1. guck dir das Pattern mal noch einmal an. Was du da machst, ist murks. Du gibst am Ende übrigens keinen Speicher wieder frei!

    #if !defined (SINGLETON_H__INCLUDED)
    #define SINGLETON_H__INCLUDED
    
    #if (_MSC_VER >= 1300)
    #pragma once
    #endif // (_MSC_VER >= 1300)
    
    template <class type>
    class singleton
    {
        singleton(singleton const&);
        singleton& operator=(singleton const&);
    
    public:
        static type& instance() { static type _inst; return _inst; }
    };
    
    #endif // SINGLETON_H__INCLUDED
    

    aber denk mal an die Probleme, die durch singletons auftreten können ...

    eines davon sind wir durch folgendes los:

    #if !defined (SINGLETON_H__INCLUDED)
    #define SINGLETON_H__INCLUDED
    
    #if (_MSC_VER >= 1300)
    #pragma once
    #endif // (_MSC_VER >= 1300)
    
    #include <memory>
    
    template <class type>
    class singleton
    {
        singleton(singleton const&);
        singleton& operator=(singleton const&);
    
    public:
        static const type* instance() { static std::auto_ptr<type>(new type) _inst; return _inst; }
    };
    
    #endif // SINGLETON_H__INCLUDED
    


  • public ANetwork, 
           util::ASingleton<CServer>
    

    Hier erbst du nur privat von dem Singleton.

    Du mußt jeweils den Zugriffsmodus angeben:

    public ANetwork, 
    public util::ASingleton<CServer>
    


  • Th schrieb:

    public ANetwork, 
           util::ASingleton<CServer>
    

    Hier erbst du nur privat von dem Singleton.

    Du mußt jeweils den Zugriffsmodus angeben:

    public ANetwork, 
    public util::ASingleton<CServer>
    

    OK genau das wars, danke.

    @ (D)Evil:
    Ich war bei den Singleton-Code (ist nichtmal von mir 😉 ) auch etwas skeptisch, allerdings schenit das durch die Template-Regeln wirklich zu funktionieren.

    Das mit dem auto_ptr dürfte doch gar nicht funktionieren so wie du das geschrieben hast?



  • @darthdespotism: Hmm ich find nur nicht die Stelle wo in deinem Singleton der Speicher wieder freigegeben wird, d.h. der Destruktor aufgerufen wird 😛
    Das mitm std::auto_ptr hab ich nicht getestet ... was geht daran denn nicht?


Anmelden zum Antworten