带引用变量的单例

时间:2012-11-26 12:48:41

标签: c++ singleton

我需要几个独特的对象,这些对象始终可用作程序运行。我遵循Singleton设计模式,它建议使用方法getInstance()来获取对象。但我更喜欢在不调用方法的情况下立即检索对象。所以我编写了一个类,它提供了几个由引用类型而不是指针返回的唯一对象。

class Priority
{
public:
    static Priority &High;
    static Priority &Medium;
    static Priority &Low;

    std::string getName(void);
    int getLevel(void);

private:
   Priority(int level, std::string const& name);
   ~Priority();
   Priority(Priority const&);
   const Priority &operator = (Priority const&);

   int level_;
   std::string name_;
};

Priority &Priority::High   = Priority(3, "High");
Priority &Priority::Medium = Priority(2, "Medium");
Priority &Priority::Low    = Priority(1, "Low");

Priority::Priority(int level, std::string const& name)
   : level_(level), name_(name)
{ }

Priority::~Priority() { }

inline std::string Priority::getName(void)
{
    return name_;
}

inline int Priority::getLevel(void)
{
    return level_;
}


我编写了一个使用上述类的示例程序。

int main()
{
    Priority &m = Priority::High;
    std::string name = m.getName();
    int level = m.getLevel();
    return 0;
}


该计划工作正常。因此我假设为变量分配了内存 在程序停止或dll文件存储该类被卸载之前,Priority &Priority::High = Priority(3, "High");将不会被删除。我是对的吗?

2 个答案:

答案 0 :(得分:1)

问题。

您显示的代码不应该编译:您不能将对非const的引用绑定到右值。

Visual C ++ 11.0和g ++ 4.7.1的示例:


[D:\dev\test]
> cl foo.cpp
foo.cpp
foo.cpp(27) : warning C4239: nonstandard extension used : 'initializing' : conversion from 'Priority' to 'Priority &'
        A non-const reference may only be bound to an lvalue
foo.cpp(28) : warning C4239: nonstandard extension used : 'initializing' : conversion from 'Priority' to 'Priority &'
        A non-const reference may only be bound to an lvalue
foo.cpp(29) : warning C4239: nonstandard extension used : 'initializing' : conversion from 'Priority' to 'Priority &'
        A non-const reference may only be bound to an lvalue

[D:\dev\test]
> gnuc foo.cpp
foo.cpp:27:48: error: invalid initialization of non-const reference of type 'Priority&' from an rvalue of type 'Priority'
foo.cpp:28:50: error: invalid initialization of non-const reference of type 'Priority&' from an rvalue of type 'Priority'
foo.cpp:29:47: error: invalid initialization of non-const reference of type 'Priority&' from an rvalue of type 'Priority'

[D:\dev\test]
> _

工具使用。

使用Visual C ++,使用选项 /W4 (警告级别4)来获取上面显示的警告。

您可以在环境变量 CL (以及同上, LINK 中添加此项和其他“使其符合标准”选项Microsoft链接器,例如/entry:mainCRTStartup作为默认链接器选项。)

[D:\dev\test]
> echo %CL%
/nologo /EHsc /GR /W4 /FI"progrock/cppx/macro/c++11.for_msvc_11.h"

[D:\dev\test]
> _

C ++解决了这个问题。

您可以使用右值引用代替左值引用,但是虽然Visual C ++对此很满意,但g ++会抱怨私有析构函数。

参考意见的内容 - 它的目的是什么? - 您可以简单地使用普通的静态数据成员。

然而,对于普通的静态数据成员,与例如迈耶斯的单身人士,你冒着敲打static initialization order fiasco的风险。所以如果你绝对必须提供全局变量,我建议使用单身人士。至于单身人士的类型,使用最简单的解决方案往往是最好的,这意味着Meyers' singletons(我只是链接了第一个看起来合理的谷歌结果)。

答案 1 :(得分:1)

这甚至不应该编译,你用临时对象初始化引用。但是,你根本不需要参考;只是直接将静态成员声明为对象:

标题:

class Priority
{
public:
    static Priority High;
    static Priority Medium;
    static Priority Low;
//...
};

在源文件中:

Priority Priority::High(3, "High");
Priority Priority::Medium(2, "Medium");
Priority Priority::Low(1, "Low");