我需要几个独特的对象,这些对象始终可用作程序运行。我遵循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");
将不会被删除。我是对的吗?
答案 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] > _
您可以使用右值引用代替左值引用,但是虽然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");