C++独特的物品
我想创建一个类,其中可能的实例范围是有限的,并且用户无法创建新实例。例如,货币是唯一的,我正在工作的图书馆的用户不应该能够创建新货币或复制现有货币。我猜这有点像多吨的模式。到目前为止我所知道的是:
#include <string>
#include <boost/smart_ptr/shared_ptr.hpp>
struct Currency {
public:
typedef const Currency * Pointer;
std::string code;
static const Currency & Get(const std::string & Code);
private:
Currency();
Currency(const std::string & c);
};
Currency::Currency(const std::string & c)
:code(c) {}
const Currency & Currency::Get(const std::string & Code) {
typedef boost::shared_ptr<Currency> Value;
typedef std::map<std::string, Value> MapType;
static std::map<std::string, Value> map_;
if (map_.empty()) {
// Initialize your map here, from a database query or what have you...
}
MapType::const_iterator it = map_.find(Code);
if (it == map_.end()) {
throw std::exception(("[Currency::Get] Currency '" + Code + "' not found").c_str());
}
return *it->second;
}
这个设计有什么明显的问题吗? (我知道这不是线程安全的) 是否有一种我不知道的普遍接受的技术/模式传统上用于实现此目的?
谢谢, 马克.
I would like to create a class where the possible universe of instances is limited, and of which users cannot create new instances. For example, currencies are unique, and users of the library I am working should not be able to create new currencies, or copy existing ones. It is kind of like a multiple-ton pattern, I guess. What I have so far is:
#include <string>
#include <boost/smart_ptr/shared_ptr.hpp>
struct Currency {
public:
typedef const Currency * Pointer;
std::string code;
static const Currency & Get(const std::string & Code);
private:
Currency();
Currency(const std::string & c);
};
Currency::Currency(const std::string & c)
:code(c) {}
const Currency & Currency::Get(const std::string & Code) {
typedef boost::shared_ptr<Currency> Value;
typedef std::map<std::string, Value> MapType;
static std::map<std::string, Value> map_;
if (map_.empty()) {
// Initialize your map here, from a database query or what have you...
}
MapType::const_iterator it = map_.find(Code);
if (it == map_.end()) {
throw std::exception(("[Currency::Get] Currency '" + Code + "' not found").c_str());
}
return *it->second;
}
Are there any obvious problems with this design? (I know that this isn't thread-safe)
Is there a generally accepted technique/pattern that I am not aware of that is traditionally used to achieve this?
Thanks,
Marc.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
声明一个私有复制构造函数
Currency::Currency(constCurrency&)
,但不定义它。这可以防止用另一个Currency
对象初始化一个Currency
对象。同样,声明一个私有赋值运算符Currency&货币::运算符=(const 货币&)
。这样您就可以防止将一种货币分配给另一种货币。Declare a private copy constructor
Currency::Currency(const Currency&)
, but don't define it. This prevents initialising aCurrency
object with anotherCurrency
object. Similarly, declare a private assignement operatorCurrency& Currency::operator=(const Currency&)
. That way you prevent assigning one currency to another currency.我相信你所说的是单例模式。所以你可以阅读一下。
在大多数语言中获得单例的方法是
1) 将构造函数设为私有
2) 在类内部实例化类的单个实例(单例)(私有静态)
3) 创建一个静态(类)方法,该方法返回指向在步骤 #2 中创建的静态私有实例的指针(通常称为 getInstance() 或 instance() 或类似的东西。)
任何需要使用此单例的人都可以调用
并使用该单例来完成他们的工作。
根据定义(我认为),单例并不是线程安全的,您注意到这一点是正确的。添加线程安全是一个单独的问题。
看起来您的解决方案已经完成了大部分工作。
What you're talking about, I believe, is the Singleton pattern. So you can read up on that.
The way in most languages to get a singleton is to
1) make your constructors private
2) instantiate a single instance (the singleton) of your class internal to the class (private static)
3) create a static (class) method that returns a pointer to the static private instance created in step #2 (typically called getInstance() or instance() or something like that.)
Anyone needing to use this singleton then calls
and uses the singleton for their work.
Singletons aren't by definition (I think) thread safe, and you're right to notice that. Adding thread safety is a separate issue.
Looks like you were most of the way there with your solution.
您已经拥有了所需的一切!
编辑:
只需修改抛出异常的部分:
您可以通过多种方式进行比较以查看该货币是否被允许:
EDIT2:
下面是与上面的答案完全不同的答案:
从问题的描述来看,您实际上可能需要考虑使用枚举而不是类来区分可能的货币类型。
编辑3:
添加如下内容:
在 Get 方法中,返回对向量中对象的引用,而不是返回“it->second”。如果尚不存在,请首先将该对象填充到向量中。
You already have everything you need!
EDIT:
Just modify the part where you throw your exception:
You can do your comparison to see if the currency is allowed in a variety of ways:
EDIT2:
Below is a completely separate answer from the one above:
From the description of your problem, you might actually want to consider using enums rather than classes to differentiate between the possible currency types.
EDIT 3:
Add something like:
And in your Get method, rather than return "it->second", return a reference to an object in the vector. If it doesn't yet exist, first populate the object into the vector.
查看
boost:noncopyable
< /a> 防止复制;这是一个很好的参考解决方案,您既可以信任又可以学习。防止实例化很容易:一个私有
构造函数。Look into
boost:noncopyable
to prevent copying; that's a good reference solution that you can both trust and learn from. Preventing instantiation is easy: aprivate
constructor.我不完全确定你想要做什么,但是当然有单例模式,如果你想将实例的数量限制为 1 或者如果你想控制实例的创建方式,你可以使用工厂模式。
I am not fully sure, what you want to do, but of course there is the singleton pattern, if you want to limit the number of instances to 1 or if you want to control how the instances are created you could use the factory pattern.