首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有没有一种方法来定义静态函数

有没有一种方法来定义静态函数
EN

Stack Overflow用户
提问于 2012-08-02 15:16:48
回答 3查看 1.9K关注 0票数 0

我有一个单例类,它只有我的MPIProxy类的一个实例(否则会导致许多构造)。

为了创建单个MPIProxy类,我有以下类型定义:

代码语言:javascript
复制
typedef Singleton<MPIProxy_> MPIProxySingleton;

但是,要访问该实例,我需要以下代码:

代码语言:javascript
复制
int myrank = MPIProxySingleton::instance().getRank();

我更喜欢允许客户端编写代码,而不是简单的MPIProxy.xy() MPIProxySingleton::instance().xy()。其中,.xy是MPIProxy_类的函数。使得上面的代码看起来像这样:

代码语言:javascript
复制
int myrank = MPIProxy.getRank();

我试过以下几种方法:

代码语言:javascript
复制
typedef MPIProxySingleton::instance() MPIProxy;

但是,这会导致编译错误:

代码语言:javascript
复制
/Users/david/Desktop/GSOC/miind/miind/./libs/MPILib/include/utilities/MPIProxy.hpp:158:31: error: C++ requires a type specifier for all declarations
typedef Singleton<MPIProxy_>::instance() MPIProxy;
~~~~~~~                       ^
/Users/david/Desktop/GSOC/miind/miind/./libs/MPILib/include/utilities/MPIProxy.hpp:158:41: error: expected ';' after top level declarator
typedef Singleton<MPIProxy_>::instance() MPIProxy;

下面是我的Singleton类的代码:

代码语言:javascript
复制
/** Singleton holder template class.
 * Template class to create singletons. A singleton instance of class
 * MyType is created and accessed using
 * \code
 * typedef Singleton<MyType> MySingletonType;
 * MyType& myRef = MySingletonType::instance()
 * // ... do something ...
 * \endcode
 */
template<class T>
class Singleton
{
public:
    // disallow creation, copying and assignment

    /** Deleted constructor to disallow explicit construction.
     * Is not defined.
     */
    Singleton()=delete;

    /** Deleted copy constructor to disallow explicit copying.
     * Is not defined.
     * @param S A singleton object.
     */
    Singleton(const Singleton& S)=delete;

    /** Deleted assignment operator to disallow explicit assignment.
     * @param S A singleton object.
     * @return The current singleton.
     */
    Singleton& operator=(const Singleton& S)=delete;

    /** Return a reference to the only instance of \c Singleton<T>.
     * @return A reference to the instance of the object.
     */
    static T& instance();

    /** Destructor.
     */
    ~Singleton();

private:


    /** Create method. Creates the singleton instance (a Meyers singleton, ie.
     * a function static object) upon the first call to \c instance().
     */
    static void create();

    /** Pointer to the instance.
     */
    static T* pInstance_;

    /** Status of the singleton. True if the singleton was destroyed.
     */
    static bool destroyed_;

};

/** Returns the unique instance of class T. If it was already
 *  deleted an exception is thrown. If the class T was never used
 *  before a new instance is generated.
 *
 * @return Unique instance of class T
 */
template<class T> T& Singleton<T>::instance()
{
    if (!pInstance_) {
        if (destroyed_) {
            // dead reference
            throw Exception("The instance was already destroyed");
        } else {
            // initial creation
            create();
        }
    }
    return *pInstance_;
}

template<class T> Singleton<T>::~Singleton()
{
    pInstance_ = 0;
    destroyed_ = true;
}

template<class T> void Singleton<T>::create()
{
    static T theInstance;
    pInstance_ = &theInstance;
}

template<class T> T* Singleton<T>::pInstance_ = 0;
template<class T> bool Singleton<T>::destroyed_ = false;

这里是我的MPIProxy_类的头

代码语言:javascript
复制
class MPIProxy_ {
public:
    /**
     * destructor
     */
    virtual ~MPIProxy_();

    /**
     * wrapper method to return the process id, if mpi is disabled it returns 0
     * @return the world rank of a process
     */
    int getRank() const;

    /**
     * wrapper method to return the size, if MPI is disabled it returns 1
     * @return
     */
    int getSize() const;

    /**
     * wrapper for mpi barrier
     */
    void barrier();

    /**
     * waits until all request stored in the vector _mpiStatus are finished
     */
    void waitAll();

    /**
     * Broadcast the value from root
     * @param value The value to be broadcast
     * @param root The root process
     */
    template<typename T>
    void broadcast(T& value, int root);

    /**
     * asynchronous receive operation the mpi status is stored in _mpiStatus
     * @param source The source of the message
     * @param tag The tag of the message
     * @param value The value received
     */
    template<typename T>
    void irecv(int source, int tag, T& value) const;

    /**
     * asynchronous send operation the mpi status is stored in _mpiStatus
     * @param dest The destination of the message
     * @param tag The tag of the message
     * @param value The value sended
     */
    template<typename T>
    void isend(int dest, int tag, const T& value) const;


private:
    /**
     * Declare the Singleton class a friend to allow construction of the MPIProxy_ class
     */
    friend class Singleton<MPIProxy_>;
    /**
     * constructor sets the MPI rank and size
     */
    MPIProxy_();

#ifdef ENABLE_MPI
    /**
     * stores the mpi statuses
     */
    static std::vector<boost::mpi::request> _mpiStatus;
#endif

    /**
     * storage of the rank to avoid function calls
     */
    static int _rank;

    /**
     * storage of the size to avoid function calls
     */
    static int _size;
};

template<typename T>
void MPIProxy_::broadcast(T& value, int root) {
#ifdef ENABLE_MPI
    mpi::communicator world;
    boost::mpi::broadcast(world, value, root);
#endif
}

template<typename T>
void MPIProxy_::irecv(int source, int tag, T& value) const {
#ifdef ENABLE_MPI
    mpi::communicator world;
    _mpiStatus.push_back(world.irecv(source, tag, value));
#else
    MPILib::utilities::Exception("MPI Code called from serial code in irecv");
#endif
}

template<typename T>
void MPIProxy_::isend(int dest, int tag, const T& value) const {
#ifdef ENABLE_MPI
    mpi::communicator world;
    _mpiStatus.push_back(world.isend(dest, tag, value));
#else
    MPILib::utilities::Exception("MPI Code called from serial code in isend");
#endif
}

typedef Singleton<MPIProxy_> MPIProxySingleton;
//typedef MPIProxySingleton::instance() MPIProxy;
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-08-02 15:23:02

在这种情况下,包装器函数总是一个很好的选择:

代码语言:javascript
复制
MPIProxy_ &  MPIProxy()
{
   return MPIProxySingleton::instance();
}

然后使用它作为:

代码语言:javascript
复制
MPIProxy().xy();
票数 3
EN

Stack Overflow用户

发布于 2012-08-02 15:52:20

我只是想展示一种略微不同的方式来完成同样的事情。由于Singleton被认为是无状态的,因此允许Singleton被实例化、复制、分配或销毁实际上没有什么坏处。它只是模板参数的单个静态实例的包装器。鉴于此,您可以这样定义您的Singleton

代码语言:javascript
复制
template <typename T>
class Singleton {
public:
    static T & instance () {
        static T instance_;
        return instance_;
    }
    T * operator -> () const { return &instance(); }
};

因此,对于要创建Singleton的对象,

代码语言:javascript
复制
class Foo_ {
    friend class Singleton<Foo_>;
    Foo_ () {}
public:
    void bar () { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};

typedef Singleton<Foo_> Foo;

然后,您可以像这样使用它:

代码语言:javascript
复制
Foo()->bar();
票数 1
EN

Stack Overflow用户

发布于 2012-08-02 15:19:19

引用它:

代码语言:javascript
复制
MPIProxy_& MPIProxy = MPIProxySingleton::instance();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11772734

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档