在一个需要实现的大型框架中定义包装类对象(在main之外)的好方法是什么,可以从任何地方访问它们。
(例如在Player.cpp等游戏对象中使用Clock.Get_Deltatime()并在main.cpp中运行Clock.Update())
我可以这样做吗?
#ifndef PLUGIN_H
#define PLUGIN_H
#include "DisplayManager.h"
#include "EventHandler.h"
#include "Time.h"
DisplayManager Display;
EventHandler Input;
Time Clock;
#endif PLUGIN_H
除了我需要访问显示,时钟和输入之外,还包括Plugin.h?考虑到这一点,单身人士和静态变量现在,但我正在寻找建议,并想知道什么将最适合这种情况(我是相对较新的C ++,没有足够的OOP经验,知道什么是最好的工具,为作业)。
答案 0 :(得分:1)
上面的代码可以使用,但您需要使用extern
关键字声明变量,以便每次包含标头时编译器都不会生成新的全局变量。在应用程序的一个位置声明没有extern
关键字的全局变量,这将是变量实际初始化的位置。
而不是上述我建议采用以下模式。我将使用DisplayManager作为示例:
DisplayManager.h:
#ifndef DISPLAY_MANAGER_H_
#define DISPLAY_MANAGER_H_
class DisplayManager {
public:
static DisplayManager* Get();
// Any other public interfaces.
private:
// Declare the constructor private or protected to prevent instances other
// than the singleton.
DisplayManager();
~DisplayManager();
// Any other private functions or members.
};
DisplayManager.cpp:
#include "DisplayManager.h"
static DisplayManager* g_display_manager;
DisplayManager* DisplayManager::Get() {
if (!g_display_manager) {
g_display_manager = new DisplayManager();
}
return g_display_manager;
}
...
这种方法将单例行为封装在类本身中。
答案 1 :(得分:1)
这个答案使用C ++ 11
在单线程环境中,单例的跟随模式运行良好:
#include <memory>
class DisplayManager
{
public:
static DisplayManager* instance()
{
static std::unique_ptr<DisplayManager> ptr(new DisplayManager);
return ptr.get();
}
private:
friend struct std::default_delete<DisplayManager>;
DisplayManager() {}
~DisplayManager() {}
DisplayManager(const DisplayManager& rhs) {}
DisplayManager& operator= (const DisplayManager& rhs) { return *this; }
};
如果您需要确保从多个线程正确访问,请将其更改为:
#include <memory>
#include <mutex>
class DisplayManager
{
public:
static DisplayManager* instance()
{
static std::unique_ptr<DisplayManager> ptr;
static std::mutex m;
if (!ptr)
{
m.lock();
if (!ptr) ptr.reset(new DisplayManager);
m.unlock();
}
return ptr.get();
}
private:
friend struct std::default_delete<DisplayManager>;
DisplayManager() {}
~DisplayManager() {}
DisplayManager(const DisplayManager& rhs) {}
DisplayManager& operator= (const DisplayManager& rhs) { return *this; }
};